这是我的代码 并链接到视频,在那里你可以看到我的“怪物” 文字 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”向前移动。
当我启动游戏时,它就像视频中那样弹回虚空
还有第二个代码变体,我没有完全中断移动,但是我可以在按下 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;
}
}
}