当 Player 与 Wall 碰撞时,它会将他弹开并向前从一堵墙发射到另一堵墙,我不知道如何解决它

问题描述 投票:0回答:1

这是我的代码 并链接到视频,在那里你可以看到我的“怪物” 文字 Player 和 Walls 有标签 - Player, Wall

对撞机

None physical Material
Is Trigger - unchecked
Radius - 0.5

和 Rididbody 与

Mass - 1
Drag - 0 
AngularDrag = 0.05
Use Gravity = unchecked
Is Kinematic = unchecked
using System.Collections; 
using System.Collections.Generic; 
using UnityEngine;

public class PlayerController : MonoBehaviour {

    public bool smoothTransition = false;
    public float transitionSpeed = 10f;
    public float transitionRotationSpeed = 500f;

    Vector3 targetGridPos;
    Vector3 prevTargetGridPos;
    Vector3 targetRotation;

    private void Start()
    {
        targetGridPos = Vector3Int.RoundToInt(transform.position);
        Collider collider = gameObject.AddComponent<BoxCollider>();
        collider.isTrigger = false;
    }

    private void FixedUpdate()
    {
        MovePlayer();
    }

    void MovePlayer()
    {
        if (true)
        {
            prevTargetGridPos = targetGridPos;

            Vector3 targetPosition = targetGridPos;

            if (targetRotation.y > 270f && targetRotation.y < 361f) targetRotation.y = 0f;
            if (targetRotation.y < 0f) targetRotation.y = 270f;

            if (!smoothTransition)
            {
                transform.position = targetPosition;
                transform.rotation = Quaternion.Euler(targetRotation);
            }
            else
            {
                transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * transitionSpeed);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(targetRotation), Time.deltaTime * transitionRotationSpeed);
            }

            // Check for collisions with walls
            Collider[] hitColliders = Physics.OverlapSphere(transform.position, 0.4f);
            foreach (Collider hitCollider in hitColliders)
            {
                Debug.Log("Collided with " + hitCollider.gameObject.name);

                if (hitCollider.gameObject.CompareTag("Wall"))
                {
                    targetGridPos = prevTargetGridPos; // move the player back to their previous position
                    break;
                }
            }
            Vector3 nextStep = targetGridPos + 2 * transform.forward;
            Collider[] nextStepHitColliders = Physics.OverlapSphere(nextStep, 0.4f);
            foreach (Collider nextStepHitCollider in nextStepHitColliders)
            {
                if (nextStepHitCollider.gameObject.CompareTag("Wall"))
                {
                    return; // don't update targetGridPos if the next step will collide with a wall
                }
            }
            targetGridPos = nextStep;
        }

        else
        {
            targetGridPos = prevTargetGridPos;
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        // Check if the collision is with a wall
        if (collision.gameObject.tag == "Wall")
        {
            // Move the player back to their previous position
            targetGridPos = prevTargetGridPos;
        }
    }


    public void RotateLeft() { if (AtRest) targetRotation -= Vector3.up * 90f; }
    public void RotateRight() { if (AtRest) targetRotation += Vector3.up * 90f; }
    public void MoveForward() { if (AtRest) targetGridPos += 2 * transform.forward; }
    public void MoveBackward() { if (AtRest) targetGridPos -= 2 * transform.forward; }
    public void MoveLeft() { if (AtRest) targetGridPos -= transform.right; }
    public void MoveRight() { if (AtRest) targetGridPos += transform.right; }


    bool AtRest
    {
        get
        {


            if ((Vector3.Distance(transform.position, targetGridPos) < 0.05f) &&
                (Vector3.Distance(transform.eulerAngles, targetRotation) < 0.05f))
                return true;
            else
                return false;
        }
    }
}

我的目标是让玩家在下一步与他碰撞时不能向墙的方向移动(例如,如果玩家按下“A”,并且按下“A”,他将与墙碰撞,什么都不会发生,但如果下一步不撞墙等,他将能够以“W”向前移动。

当我启动游戏时,它就像视频中那样弹回虚空

c# unity3d controller
1个回答
0
投票

还有第二个代码变体,我没有完全中断移动,但是我可以在按下 WASD 的同时向墙移动,如果我在墙上移动,玩家会绊倒它并弹开,然后移动中断。

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

public class PlayerController : MonoBehaviour
{

    public bool smoothTransition = false;
    public float transitionSpeed = 10f;
    public float transitionRotationSpeed = 500f;

    Vector3 targetGridPos;
    Vector3 prevTargetGridPos;
    Vector3 targetRotation;

    private void Start()
    {
        targetGridPos = Vector3Int.RoundToInt(transform.position);
        Collider collider = gameObject.AddComponent<BoxCollider>();
        collider.isTrigger = false;
    }

    private void FixedUpdate()
    {
        MovePlayer();
    }

    void MovePlayer()
    {
        if (true) // here is an error?
        {
            prevTargetGridPos = targetGridPos;

            Vector3 targetPosition = targetGridPos;

            if (targetRotation.y > 270f && targetRotation.y < 361f) targetRotation.y = 0f;
            if (targetRotation.y < 0f) targetRotation.y = 270f;

            if (!smoothTransition)
            {
                transform.position = targetPosition;
                transform.rotation = Quaternion.Euler(targetRotation);
            }
            else
            {
                transform.position = Vector3.MoveTowards(transform.position, targetPosition, Time.deltaTime * transitionSpeed);
                transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(targetRotation), Time.deltaTime * transitionRotationSpeed);
            }

            // Check for collisions with walls
            Collider[] hitColliders = Physics.OverlapSphere(transform.position, 0.4f);
            foreach (Collider hitCollider in hitColliders)
            {
                Debug.Log("Collided with " + hitCollider.gameObject.name);

                if (hitCollider.gameObject.CompareTag("Wall"))
                {
                    targetGridPos = prevTargetGridPos; // move the player back to their previous position
                    break;
                }
            }
        }
        else
        {
            targetGridPos = prevTargetGridPos;
        }
    }

    void OnCollisionEnter(Collision collision)
    {
        // Check if the collision is with a wall
        if (collision.gameObject.tag == "Wall")
        {
            // Move the player back to their previous position
            targetGridPos = prevTargetGridPos;
        }
    }


    public void RotateLeft() { if (AtRest) targetRotation -= Vector3.up * 90f; }
    public void RotateRight() { if (AtRest) targetRotation += Vector3.up * 90f; }
    public void MoveForward() { if (AtRest) targetGridPos += 2 * transform.forward; }
    public void MoveBackward() { if (AtRest) targetGridPos -= 2 * transform.forward; }
    public void MoveLeft() { if (AtRest) targetGridPos -= transform.right; }
    public void MoveRight() { if (AtRest) targetGridPos += transform.right; }


    bool AtRest
    {
        get
        {


            if ((Vector3.Distance(transform.position, targetGridPos) < 0.05f) &&
                (Vector3.Distance(transform.eulerAngles, targetRotation) < 0.05f))
                return true;
            else
                return false;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.