Unity组件开发--升降梯

发布时间:2024年01月05日

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

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;
                }
            }

              
        }
    }

    
}

文章来源:https://blog.csdn.net/woshiyuyanjia/article/details/135403582
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。