我的可玩角色遇到障碍物时会向左或向右旋转

问题描述 投票:-1回答:2

我的可玩角色在遇到对撞机障碍物时向左或向右旋转。这是正常现象,但是我想知道是否可以禁用它。

unity3d rotation collision-detection collision collider
2个回答
0
投票

这是脚本

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

public class PlayerMotor : MonoBehaviour
{
    public Vector3 startPosition;
    private const float LANE_DISTANCE = 3.0f;
    private const float TURN_SPEED = 0.5f;

    //Functionality
    private bool isRunning = false;
    public bool isClimbing = false;

    private readonly object down;
    private CharacterController controller;

    [SerializeField]
    private float jumpForce = 5.0f;
    private float verticalVelocity = 0.0f;
    private float gravity = 10.0f;

    //Speed
    private float originalSpeed = 4.0f;
    private float speed = 4.0f;
    private float speedIncreaseLastTick;
    private float speedIncreaseTime = 2.5f;
    private float speedIncreaseAmount = 0.1f;

    private float climbingSpeed = 1.0f;

    private int desiredLane = 0; //0 = left, 1 = middle, 2 = right

    private Animator anim;

    // Start is called before the first frame update
    void Start()
    {
        speed = originalSpeed;
        controller = GetComponent<CharacterController>();
        anim = GetComponent<Animator>();
        transform.position = startPosition;
}

    // Update is called once per frame
    void Update()
    {
        if (isClimbing)
        {
            transform.Translate(Vector3.up * climbingSpeed * Time.deltaTime);
        }


        if (!isRunning)
            return;

        if (Time.time - speedIncreaseLastTick > speedIncreaseTime)
        {
            speedIncreaseLastTick = Time.time;
            speed += speedIncreaseAmount;
            //GameManager.Instance.UpdateScores();
        }

        // Gather the inputs on wich lane we should be
        if (MobileInput.Instance.SwipeLeft)
        {
            MoveLane(false);
        }

        if (MobileInput.Instance.SwipeRight)
        {
            MoveLane(true);
        }

        // Calculate where we should be horizontally

        Vector3 targetPosition = transform.position.z * Vector3.forward;
        int posX = Mathf.Abs(desiredLane);

        if (desiredLane < 0)
            targetPosition += Vector3.left * posX * LANE_DISTANCE;
        else if (desiredLane > 0)
            targetPosition += Vector3.right * posX * LANE_DISTANCE;



        //Calculate move delta
        Vector3 moveVector = Vector3.zero;
        moveVector.x = (targetPosition - transform.position).normalized.x * speed;

        bool isGrounded = IsGrounded();
        anim.SetBool("Grounded", isGrounded);

        //Calculate y
        if (isGrounded)     //If grounded
        {
            verticalVelocity = -0.1f;

            if (MobileInput.Instance.SwipeUp)
            {
                //Jump
                anim.SetTrigger("Jump");
                verticalVelocity = jumpForce;
            }
            else if (MobileInput.Instance.SwipeDown)
            {
                //Slide
                StartSliding();
                Invoke("StopSliding", 1.0f);
            }
        }
        else
        {
            verticalVelocity -= (gravity * Time.deltaTime);

            //Fast falling machanics
            if (MobileInput.Instance.SwipeDown)
            {
                verticalVelocity = -jumpForce;
            }
        }

        moveVector.y = verticalVelocity;
        moveVector.z = speed;

        //Move the character
        controller.Move(moveVector * Time.deltaTime);

        //Rotate the player where is going

        Vector3 dir = controller.velocity;
        if (dir!= Vector3.zero)
        {
            dir.y = 0;
            transform.forward = Vector3.Lerp(transform.forward, dir, TURN_SPEED);
        }

    }

    // This function (MoveLane) allows the player to move to the left and to the right
    private void MoveLane(bool goingRight)
    {

        if (!goingRight)
        {
            desiredLane--;
            if (desiredLane == -6)
                desiredLane = -5;
        }

        if (goingRight)
        {
            desiredLane++;
            if (desiredLane == 6)
                desiredLane = 5;
        }


        /* We wan rewrite the above function like this below
        desiredLane += (goingRight) ? 1 : -1;
        Mathf.Clamp(desiredLane, -5, 5);
        */
    }

    private bool IsGrounded()
    {
        Ray groundRay = new Ray(new Vector3(controller.bounds.center.x, (controller.bounds.center.y - controller.bounds.extents.y) + 0.2f, 
                                controller.bounds.center.z), Vector3.down);
        Debug.DrawRay(groundRay.origin, groundRay.direction, Color.cyan, 1.0f);

        return (Physics.Raycast(groundRay, 0.2f + 0.1f));
    }

    public void StartRunning ()
    {
        isRunning = true;
        anim.SetTrigger("StartRunning");
    }

    private void StartSliding()
    {
        anim.SetBool("Sliding", true);
        controller.height /= 2;
        controller.center = new Vector3(controller.center.x, controller.center.y / 2, controller.center.z);
    }

    private void StopSliding()
    {
        anim.SetBool("Sliding", false);
        controller.height *= 2;
        controller.center = new Vector3(controller.center.x, controller.center.y * 2, controller.center.z);
    }

    private void Crash()
    {
        anim.SetTrigger("Death");
        isRunning = false;
    }

    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        switch(hit.gameObject.tag)
        {
            case "Obstacle":
                Crash();
            break;
        }

    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "Ladder")
        {
            isRunning = false;
            isClimbing = true;
            anim.SetBool("ClimbingLadder", true);
        }

        else if (other.gameObject.tag == "LadderCol2")
        {
            isClimbing = false;
            anim.SetBool("ClimbingLadder", false);
            transform.Translate(Vector3.forward * 1);
            isRunning = true;
        }
    }

}

0
投票

我看到了问题。来自这些行

Vector3 dir = controller.velocity; 
if (dir!= Vector3.zero) 
{ dir.y = 0; 
   transform.forward =   
   Vector3.Lerp(transform.forward, dir,   
    TURN_SPEED);
 } 

我添加了它们,以便在播放器向左或向右旋转时旋转播放器一点。

© www.soinside.com 2019 - 2024. All rights reserved.