我如何检查地形边界以避免角色走出去摔倒?

How can i check the Terrain bounds to avoid the characters from walking out and falling?

在顶部

public GameObject[] waypoints;
public Transform target;
public float moveSpeed = 1f;
public float rotationSpeed = 1f;
Transform myTransform;

public float walkSpeed = 10f;
public ThirdPersonCharacter[] thirdPersonCharacter;

Vector3 boundLower;
Vector3 boundUpper;
public Terrain terrain;

醒来并开始:

void Awake()
{
    myTransform = transform;
}

void Start()
{
    GameObject tpc1 = GameObject.Find("ThirdPersonController");
    thirdPersonCharacter[0] = tpc1.GetComponent<ThirdPersonCharacter>();
    GameObject tpc2 = GameObject.Find("ThirdPersonController (1)");
    thirdPersonCharacter[1] = tpc2.GetComponent<ThirdPersonCharacter>();

    waypoints = GameObject.FindGameObjectsWithTag("ClonedObject");

    boundLower = terrain.transform.position - terrain.terrainData.size / 2;
    boundUpper = terrain.transform.position + terrain.terrainData.size / 2;
}

更新:

void Update()
{
    thirdPersonCharacter[0].m_MoveSpeedMultiplier = walkSpeed;
    thirdPersonCharacter[1].m_MoveSpeedMultiplier = walkSpeed;
    WayPoints();
    CheckBounds();
}

WayPoints:

int index = 0;

private void WayPoints()
{
    if (index == waypoints.Length)
        index = 0;

    target = waypoints[index].transform;
    float distance = Vector3.Distance(myTransform.position, target.transform.position);

    myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
          Quaternion.LookRotation(target.position - myTransform.position),
          rotationSpeed * Time.deltaTime);

    myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;

    if (distance < 2f)
        index++;
}

和 CheckBounds:

private Vector3 direction = Vector3.forward;

void CheckBounds()
{
    foreach (var child in thirdPersonCharacter)
    {
        var pos = child.transform.position;
        pos.x = Mathf.Clamp(pos.x, boundLower.x, boundUpper.x);
        pos.z = Mathf.Clamp(pos.z, boundLower.z, boundUpper.z);
        if (pos.x == boundLower.x || pos.x == boundUpper.x) direction.x = -direction.x;
        if (pos.z == boundLower.z || pos.z == boundUpper.z) direction.z = -direction.z;
        child.transform.position = pos;
    }
}

一旦我添加了 CheckBounds 函数并从 Update 函数中调用它,角色就会原地踏步。没有移动。没有 checkBounds,他们在 waypoints 之间走得很好。我想做的是,如果角色走到地形边缘(边界),就让他 turn/rotate 返回或停在原地。

我必须说角色 (ThirdPersonController) 正在移出地形边界并且仅当我将步行速度更改为 30 或更高时才会下降。但无论如何,我想知道如何在其他情况下使用 CheckBounds,例如,如果玩家只是走到地形边界。

有很多方法可以为游戏制作 Boundary。 Unity 网络上的第 1 和第 2 教程中有一个示例:

https://unity3d.com/learn/tutorials/projects/roll-ball-tutorial/setting-play-area?playlist=17141

https://unity3d.com/learn/tutorials/projects/space-shooter-tutorial/boundary?playlist=17147

您可以通过 3 种方式完成:

  • 在地图周围创建“Boundary”对象,创建Trigger,一旦有人按下扳机,推他back/stop him/don不允许他通过
  • 创建填充整个地图的“Boundary”对象。在 OnExit 方法上创建 Trigger 一旦某个对象试图离开,停止 him/push back/don 不允许他通过
  • 坚持编程和一些您知道 Boundaries 位置的 "map" 概念。在这种情况下,你必须检查位置,每当对象离开边界时,你必须阻止他——这必须在每个更新帧发生,而不仅仅是在触发器上

根据地图的大小和游戏的复杂程度,我会选择一个最佳答案。一旦游戏变得复杂,您必须在引擎中创建自己的引擎来处理地图控制和其他事情。但首先:循序渐进。

此代码应该有效(一旦有人越过边界,设置为边界位置 + 进入地图中心的最小步数):

var pos = child.transform.position;
float step = 1; //adjust to fit scale/size of step

if (pos.x <= boundLower.x) pos.x = boundLower.x + step;
if (pos.x >= boundUpper.x) pos.x = boundUpper.x - step;
if (pos.z <= boundLower.z) pos.z = boundLower.z + step;
if (pos.z >= boundUpper.z) pos.z = boundUpper.z - step;

child.transform.position = pos;