unity3D实现完美跳跃

1.Destroyer

using UnityEngine;

public class Destroyer : MonoBehaviour
{
    
    
    [SerializeField] private float lifeTimer;

    private void Start()
    {
    
    
        Destroy(gameObject, lifeTimer);
    }
}

2.Echo

using UnityEngine;

public class Echo : MonoBehaviour
{
    
    
    private Jump jump;
    public GameObject echo;

    private float timeBtSpawn;
    [SerializeField] private float spawnRate;

    private void Start()
    {
    
    
        jump = GetComponent<Jump>();
    }

    private void Update()
    {
    
    
        if (jump.GetComponent<Rigidbody2D>().velocity.x != 0)
        {
    
    
            if (timeBtSpawn >= spawnRate)
            {
    
    
                if (jump.moveH > 0)
                {
    
    
                    GameObject instance = Instantiate(echo, transform.position, Quaternion.identity);
                    Destroy(instance, 2.0f);
                    timeBtSpawn = 0;
                }

                if (jump.moveH < 0)
                {
    
    
                    GameObject instance = Instantiate(echo, transform.position, Quaternion.identity);
                    instance.transform.eulerAngles = new Vector3(0, 180, 0);
                    Destroy(instance, 2.0f);
                    timeBtSpawn = 0;
                }
            }
            else
            {
    
    
                timeBtSpawn += Time.deltaTime;
            }
        }
    }
}

3.Jump

using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
public class Jump : MonoBehaviour
{
    
    
    private Rigidbody2D rb;
    [SerializeField] private float jumpForce; //ADD One force whenn jump

    [HideInInspector] public float moveH;
    [SerializeField] private float moveSpeed;
    private SpriteRenderer sp;
    [SerializeField] private bool isGround;

    public Transform checkPoint;
    [SerializeField] private float checkRadius;
    public LayerMask layerMask;
    [SerializeField] private Vector2 checkBoxSize;

    [Header("Better Jump")]
    //[SerializeField] private float jumpFactor;
    [SerializeField]
    private float fallFactor;

    [SerializeField] private float shortJumpFactor;

    [Header("Second Jump")] [SerializeField]
    private float jumpTimes; //MARKER Double Jump

    [Header("VFX")] [SerializeField] private GameObject jumpEffect;

    private void Start()
    {
    
    
        rb = GetComponent<Rigidbody2D>();
        sp = GetComponent<SpriteRenderer>();
        Physics2D.queriesStartInColliders = false; //确保游戏一开始,射线从某个含有Collider组件的内部发出,会忽略这个Collider组件对象的检测
    }

    private void Update() //0.02s
    {
    
    
        if (Input.GetKeyDown(KeyCode.Space) && isGround)
            //if(Input.GetKeyDown(KeyCode.Space) && jumpTimes > 1)//MARKER Double Jump
        {
    
    
            rb.velocity = Vector2.up * jumpForce;
            Instantiate(jumpEffect, transform.position - Vector3.up, Quaternion.identity);

            //jumpTimes--;//MARKER Double Jump
            //Debug.Log(jumpTimes);//MARKER Double Jump
        }

        moveH = Input.GetAxis("Horizontal") * moveSpeed;
        rb.velocity = new Vector2(moveH, rb.velocity.y);

        //Debug.Log(moveH);//MARKER 如果角色向左移动,moveH为负数;如果向右边移动,则大于零

        Flip();
        CheckGround();
        BetterJump();
    }

    //检测能否跳跃 => 二段跳 TODO Later
    private void CheckGround()
    {
    
    
        #region Raycast Method has Disadvantage

        //RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, -transform.up, sp.bounds.extents.y + 0.1f);
        //Debug.DrawRay(transform.position, -transform.up * (sp.bounds.extents.y + 0.1f), Color.red);

        #endregion

        //Collider2D collider = Physics2D.OverlapCircle(checkPoint.position, checkRadius, layerMask);
        Collider2D collider = Physics2D.OverlapBox(checkPoint.position, checkBoxSize, 0, layerMask);

        if (collider != null) //我们检测到了平台
        {
    
    
            isGround = true;
            //jumpTimes = 2;//MARKER Double Jump
        }
        else
        {
    
    
            isGround = false;
        }
    }

    //可视化
    private void OnDrawGizmos()
    {
    
    
        //Gizmos.DrawWireSphere(checkPoint.position, checkRadius);
        Gizmos.DrawWireCube(checkPoint.position, checkBoxSize);
        Gizmos.color = Color.green;
    }

    //TODO 其他翻转的方法:LocalScale.x / RotationY / trans.eulerAngles / transform.Rotate(Vector3.up * 180)
    private void Flip()
    {
    
    
        if (moveH > 0)
        {
    
    
            //sp.flipX = false;
            transform.eulerAngles = new Vector3(0, 0, 0);
        }
        else if (moveH < 0)
        {
    
    
            //sp.flipX = true;
            transform.eulerAngles = new Vector3(0, 180, 0);
        }
    }

    //更好的跳跃效果
    private void BetterJump()
    {
    
    
        if (rb.velocity.y < 0) //MARKER 角色下落时,速度会越来越快
        {
    
    
            rb.velocity += Vector2.up * Physics2D.gravity.y * fallFactor * Time.deltaTime;
        }
        else if (rb.velocity.y > 0 && !Input.GetKey(KeyCode.Space))
        {
    
    
            rb.velocity += Vector2.up * Physics2D.gravity.y * shortJumpFactor * Time.deltaTime;
        }
    }

    //MARKER 跳跃的几种方式
    //private void PlayerJump()
    //{
    
    
    //rb.AddForce(new Vector2(0, jumpForce));//f * t = m * v => v = jumpForce * 0.02 / 1 OPTIONAL 1
    //rb.AddForce(Vector2.up * jumpForce);//OPTIONAL 2
    //rb.AddForce(transform.up * jumpForce);//OPTIONAL 3
    //}
}

4.Light

using UnityEngine;

public class Light : MonoBehaviour
{
    
    
    [SerializeField] private float rotateSpeed;

    private void Update()
    {
    
    
        transform.Rotate(0, 0, rotateSpeed * Time.deltaTime);
    }
}

5.OneWayPlatform

using UnityEngine;

public class OneWayPlatform : MonoBehaviour
{
    
    
    private PlatformEffector2D platformEffect2D;
    public float holdTime;

    private void Start()
    {
    
    
        platformEffect2D = GetComponent<PlatformEffector2D>();
    }

    private void Update()
    {
    
    
        if (Input.GetKeyUp(KeyCode.S))
        {
    
    
            holdTime = 0.5f;
        }

        if (Input.GetKey(KeyCode.S))
        {
    
    
            if (holdTime <= 0)
            {
    
    
                platformEffect2D.rotationalOffset = 180f;
                holdTime = 0.5f;
            }
            else
            {
    
    
                holdTime -= Time.deltaTime;
            }
        }

        if (Input.GetKey(KeyCode.Space))
        {
    
    
            platformEffect2D.rotationalOffset = 0f;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36382679/article/details/113725195