Unity组件开发--升降梯

news2024/12/24 21:29:04

        我开发的升降梯由三个部分组成,反正适用于我的需求了,其他人想复用到自己的项目的话,不一定。写的也不是很好,感觉搞的有点复杂啦。完全可以在优化一下,项目赶工期,就先这样吧。能用就行,其他的再说。

1.升降梯基类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class LiftObjCtrBase : MonoBehaviour
{
    public float speed = 5f;  // 上升和下降的速度
    public LiftObjCtrBase targetObject;  // 指定的物体高度

    [HideInInspector]
    public bool isRising = false;  // 是否正在上升
    [HideInInspector]
    public bool isFalling = false;  // 是否正在下降
    [HideInInspector]
    public bool isPlayerStay = false; //玩家是否在上面
    [HideInInspector]
    public Vector3 initialPosition;  // 初始位置
    [HideInInspector]
    public float offsetY = 0;
    [HideInInspector]
    public Transform playerTra;
    [HideInInspector]
    public Transform targetTra;
    [HideInInspector]
    public float radius = 0;
    // Start is called before the first frame update
    [HideInInspector]
    public bool isReach = false;

    public virtual bool isTriggerEnter(Transform playerTra) {
        if (Vector3.Distance(gameObject.transform.position, playerTra.position) > radius)
        {
            return false;
        }
        else
        {

            return true;
        }
    }

    public virtual void startRising() {
    
    }

}

2.玩家接触到的头一个升降梯:第一个升降梯的碰撞组件,必须开启isTrigger属性;注意:所有升降梯都需要挂碰撞组件

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.TextCore.Text;

public class LiftFirstObjCtr : LiftObjCtrBase
{
    
    //private Transform player;  // 角色
    private void Start()
    {
        initialPosition = transform.position;  // 记录初始位置
        targetTra = targetObject.gameObject.transform;
        MeshCollider meshCollider = gameObject.GetComponent<MeshCollider>();
        radius = meshCollider.bounds.extents.magnitude;
    }

    private void Update()
    {
        if (targetObject == null) return;

        if (playerTra != null && !isTriggerEnter(playerTra) && !isFalling)
        {

            isPlayerStay = false;
            isFalling = true;
            isRising = false;
            
        }

        if (playerTra !=null && targetObject.isTriggerEnter(playerTra) && !targetObject.isRising && !targetObject.isReach)
        {

            isPlayerStay = false;
            isFalling = true;
            targetObject.startRising();
            
        }
        
        if (isRising && isPlayerStay)
        {
            // 上升逻辑

            if (playerTra == null || offsetY == 0) return;
            transform.Translate(Vector3.up * speed * Time.deltaTime);
            playerTra.position = new Vector3(playerTra.position.x, transform.position.y+ offsetY+0.4f, playerTra.position.z);
            
            // 到达目标高度后开始下降
            if (transform.position.y >= targetTra.position.y)
            {

                gameObject.GetComponent<Collider>().isTrigger = false;
                
                isRising = false;
                
            }
        }
        else if (isFalling && !isPlayerStay)
        {
            // 下降逻辑
            transform.Translate(Vector3.down * speed * Time.deltaTime);

            // 返回初始位置后停止下降
            if (transform.position.y <= initialPosition.y)
            {
                transform.position = initialPosition;
                isFalling = false;
                gameObject.GetComponent<Collider>().isTrigger = true;
            }
        }
       

    }

    

    

    private void OnTriggerEnter(UnityEngine.Collider other)
    {
        
        if (other.gameObject.tag == "Player")
        {
            Debug.Log("玩家撞到升降梯");
            
        }
    }


    public override bool isTriggerEnter(Transform playerTra) {
        // 检测角色是否在碰撞器范围内
        if (Vector3.Distance(gameObject.transform.position, playerTra.position) > radius)
        {
            return false;
        }
        else {

            return true;
        }
    }
   

    private void OnTriggerStay(UnityEngine.Collider other)
    {
        
        if (other.gameObject.tag == "Player" && !isPlayerStay)
        {
            if (Vector3.Distance(other.gameObject.transform.position, gameObject.transform.position)< radius) {
                Debug.Log("玩家待在升降梯");
                isRising = true;

                playerFollow(other.gameObject);
                gameObject.GetComponent<Collider>().isTrigger = false;
            }
            
        }

    }

    


    

    private void OnTriggerExit(UnityEngine.Collider other)
    {
        
        
    }

    private void playerFollow(GameObject player) {

        
        offsetY = player.transform.position.y - transform.position.y;
        playerTra = player.transform;
        isPlayerStay = true;
    }

    public override void startRising()
    {
        
    }
}

3.中间的其他升降梯,其他中间的升降梯由于是悬浮在空中的,所以需要不能开启isTrigger属性,否则玩家碰到后就会掉下去:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.TextCore.Text;

public class LiftMiddleObjCtr : LiftObjCtrBase
{
    public LiftObjCtrBase preLiftObj;
    // Update is called once per frame
    
    private void Start()
    {
        initialPosition = transform.position;  // 记录初始位置
        targetTra = targetObject.transform;
        MeshCollider meshCollider = gameObject.GetComponent<MeshCollider>();
        radius = meshCollider.bounds.extents.magnitude;
    }


    void Update()
    {

        if (targetObject == null) return;

        if (playerTra != null && !isTriggerEnter(playerTra) && !isFalling)
        {

            isPlayerStay = false;
            isFalling = true;
            isRising = false;
            return;
        }

        if (playerTra != null && targetObject.isTriggerEnter(playerTra) && !targetObject.isRising)
        {

            isPlayerStay = false;
            isFalling = true;
            targetObject.startRising();
            playerTra = null;
        }

        if (isRising && isPlayerStay)
        {
            // 上升逻辑
            if (playerTra == null || offsetY == 0) return;

            transform.Translate(Vector3.up * speed * Time.deltaTime);
            playerTra.position = new Vector3(playerTra.position.x, transform.position.y + offsetY + 0.4f, playerTra.position.z);
            
            // 到达目标高度后开始下降
            if (transform.position.y >= targetTra.position.y)
            {

                isRising = false;
                isReach = true;
            }
        }
        else if (isFalling && !isPlayerStay)
        {
            // 下降逻辑
            transform.Translate(Vector3.down * speed * Time.deltaTime);

            // 返回初始位置后停止下降
            if (transform.position.y <= initialPosition.y)
            {
                transform.position = initialPosition;
                isFalling = false;
                isReach = false;
                isRising = false;
            }
        }
        
    }

    public override bool isTriggerEnter(Transform playerTra)
    {

        if (Vector3.Distance(gameObject.transform.position, playerTra.position) > radius)
        {
            return false;
        }
        else
        {

            return true;
        }
    }

    public override void startRising() {

        
        isRising = true;

        playerFollow(preLiftObj.playerTra.gameObject);
        gameObject.GetComponent<Collider>().isTrigger = false;
    }

    private void playerFollow(GameObject player)
    {


        offsetY = player.transform.position.y - transform.position.y;
        playerTra = player.transform;
        isPlayerStay = true;
    }
}

4.最后一个升降梯,是玩家最终达到的升降梯,所以可以不用升降,他是出发倒数第二个升降梯的下降:感觉有点奇怪,反正整个组件都开发的感觉奇奇怪怪的,算了算了,咱也没啥要求,混口饭吃,能较差就行

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LiftLastObjCtr : LiftObjCtrBase
{
    // Start is called before the first frame update
    public LiftMiddleObjCtr middleObject;

    public override bool isTriggerEnter(Transform playerTra)
    {
        return false;
    }

    public override void startRising()
    {
        
    }



    // Update is called once per frame
    void Update()
    {



        if (middleObject != null && middleObject.playerTra != null) {

            if (Vector3.Distance(middleObject.playerTra.position,gameObject.transform.position) < 1) {
                if (Vector3.Distance(middleObject.playerTra.position, middleObject.gameObject.transform.position) > 1)
                {

                    middleObject.isFalling = true;
                    middleObject.isPlayerStay = false;
                }
            }

              
        }
    }

    
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1361213.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MidJourney笔记(10)-faq-fast-help-imagine-info-public-stealth

/faq 在官方 Midjourney Discord 服务器中使用可快速生成流行提示工艺频道常见问题解答的链接。 不过这个命令,我也是没有找到入口,之前还能在MidJourney的频道里使用,然后最近发现没有权限,有点奇怪。不知道系统又做了什么升级。 /fast 切换到快速模式。

Vue3-34-路由-路由配置参数 props

说明 路由的路径中可以携带参数&#xff0c; 形式如 &#xff1a;/a/:pname &#xff0c;这个:表示这是个参数&#xff0c;pname &#xff1a;表示 参数名称。 在组件中&#xff0c;可以通过 当前路由对象的 params 属性来获取到这个参数&#xff0c; 当前路由对象 可以通过 us…

Flutter 混合开发 - aar打包

背景 项目接入 Flutter 后有两种方式&#xff0c;一种是 module 引入开发&#xff0c;一种是 aar 依赖开发。当前项目中在 Debug 阶段为了方便调试采用 module 开发&#xff0c;在发版时&#xff08;即 Release 阶段&#xff09;采用 aar 依赖引入。为了配合这种模式就需要在 …

SpringBoot中动态注册接口

1. 说明 接口注册&#xff0c;使用RequestMappingHandlerMapping来实现mybatis中动态执行sql使用github上的SqlMapper工具类实现 2. 核心代码片段 以下代码为spring动态注册接口代码示例 Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping;publ…

手机上连网络转接app,电脑连接手机,共用网络转接app的办法

方法一&#xff0c;&#xff08;不推荐&#xff09; 因为太简单了所以写一下 电脑安装MuMu模拟器&#xff0c;之后安装网络转接app&#xff0c;这个模拟器设置了从电脑上安装app和&#xff0c;安卓与电脑同步文件夹功能&#xff0c;实现文件共享。所以直接用就可以了。 方法二…

彻底认识Unity ui设计中Space - Overlay、Screen Space - Camera和World Space三种模式

文章目录 简述Screen Space - Overlay优点缺点 Screen Space - Camera优点缺点 World Space优点缺点 简述 用Unity中开发了很久&#xff0c;但是对unity UI管理中Canvas组件的Render Mode有三种主要类型&#xff1a;Screen Space - Overlay、Screen Space - Camera和World Spa…

OR-3150:IGBT驱动光耦,可替代HCPL3150

具有MOSFET高输入阻抗和GTR低导通压降特性提供隔离反馈 高隔离电压 1.5A输出电流 工业温度范围&#xff1a;–40C 至 110C 宽工作 VCC 范围 特征 VCM 1500V 时最小共模抑制 &#xff08;CMR&#xff09; 为 35 kV/μs 最大低电平输出电压 &#xff08;VOL&#xff09; 1.0…

ERROR:SyntaxError: Non-ASCII character ‘\xc3‘ in file

报错信息&#xff1a; SyntaxError: Non-ASCII character ‘\xc3’ in file /home/user/ROSpy-LeaderFollower/src/follow_/src/scripts/tb3_flw.py on line 46, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details 解决办法&#xff1a; pyt…

数据的创建、调用、修改、删除存储过程,以及第一类丢失更新(回滚丢失)和 第二类丢失更新(覆盖丢失/两次更新问题)

数据的创建存储过程、调用存储过程、修改存储过程、删除存储过程&#xff0c;以及第一类丢失更新&#xff08;回滚丢失&#xff09;和 第二类丢失更新&#xff08;覆盖丢失/两次更新问题&#xff09; 文章目录 一、创建存储的语法二、调用存储过程三、修改存储过程四、删除存储…

码云Gitee复制 GitHub 项目

码云提供了直接复制 GitHub 项目的功能&#xff0c;方便我们做项目的迁移和下载。 1.新建仓库 2.导入仓库 3.强制同步 如果 GitHub 项目更新了以后&#xff0c;在码云项目端可以手动重新同步&#xff0c;进行更新&#xff01;

Vue3-36-路由-路由的元数据信息 meta

什么是 meta 简单的理解&#xff0c;meta 就是路由对象 的一个属性对象&#xff0c; 可以 通过这个 属性给 路由对象添加 一些必要的属性值&#xff0c; 在使用路由对象时可以获取到这个属性型对象&#xff0c;从而进行一些其他的逻辑判断。 meta 这个非常的简单&#xff0c;就…

将yolov8的检测框从正框修改为旋转框需要做那些修改?

将yolov8项目修改为yolov8_obb项目需要修改模型结构(增加角度预测)、dataloader(使其支持dota格式数据)、修改TaskAlignedAssigner(使其支持带角度的bbox)、修改loss(新增对角度的训练)、修改metric(将hbb指标titile修改为obb)、修改绘图代码(使其能绘制旋转框)。 …

Flink窗口与WaterMark

本文目录 窗口的生命周期Window Assigners窗口函数&#xff08;Window Functions&#xff09;TriggersEvictorsAllowed Lateness 窗口 窗口&#xff08;Window&#xff09;是处理无界流的关键所在。窗口可以将数据流装入大小有限的“桶”中&#xff0c;再对每个“桶”加以处理。…

K8S陈述式资源管理(1)

命令行: kubectl命令行工具 优点: 90%以上的场景都可以满足对资源的增&#xff0c;删&#xff0c;查比较方便&#xff0c;对改不是很友好 缺点:命令比较冗长&#xff0c;复杂&#xff0c;难记声明式 声明式&#xff1a;K8S当中的yaml文件来实现资源管理 GUI&#xff1a;图形…

box-shadow参数学习及渲染过程研究

参数定义 CSS 的 box-shadow 属性用于在元素的框架周围添加阴影效果。它可以接受多个由逗号分隔的阴影效果&#xff0c;每个阴影效果由以下几部分组成&#xff1a; h-offset&#xff1a;水平阴影的位置。正值将阴影向右移动&#xff0c;负值将阴影向左移动。v-offset&#xf…

vue-video-player播放hls视频流

需求 最近需要接入海康视频摄像头&#xff0c;然后把视频的画面接入到自己的网站系统中。以前对接过rtsp固定IP的显示视频&#xff0c;这次的不一样&#xff0c;没有了固定IP。海康的解决办法是&#xff0c;摄像头通过配置服务器到萤石云平台&#xff0c;然后购买企业版账号和…

【unity小技巧】实现没有动画的FPS武器摇摆和摆动效果

文章目录 前言开始完结 前言 添加程序摇摆和摆动是为任何FPS游戏添加一些细节的非常简单的方法。但是并不是所以的模型动画都会配有武器摆动动画效果&#xff0c;在本文中&#xff0c;将实现如何使用一些简单的代码实现武器摇摆和摆动效果&#xff0c;这比设置动画来尝试实现类…

调整几行代码,接口吞吐提升 10 倍,性能调优妙啊!

景 分析过程 总结 背景 公司的一个ToB系统,因为客户使用的也不多,没啥并发要求,就一直没有经过压测。这两天来了一个“大客户”,对并发量提出了要求:核心接口与几个重点使用场景单节点吞吐量要满足最低500/s的要求。 当时一想,500/s吞吐量还不简单。Tomcat按照100个线程…

小心JDK20 ZipOutputStream

Oracle 團隊竟然這麽粗心&#xff0c;編譯JDK 20 時ZipOutputStream沒有編譯成功就發佈了。 所以這個20版本不可以使用ZipOutputStream。 GZIPInputStream 只能做最後的壓縮&#xff0c;不能添加多個附件ZipEntry。 下一個版本21不存在這個問題。 try(var zipOut new ZipOu…

C++之STL库简介

目录 一、STL&#xff08;Standard Template Library&#xff0c;标准模板库&#xff09; 二、容器&#xff08;Containers&#xff09; 1.vector&#xff08;动态数组&#xff09; 2.list&#xff08;双向链表&#xff09; 3.deque&#xff08;双端队列&#xff09; 4.st…