1

我为我的游戏创建了一些移动平台。有一个名为 PlatformPath1 的游戏对象,它的子对象定义了平台循环的开始和结束,然后显然是遵循路径的实际平台。平台移动完美,但正如预期的那样,玩家不会随着平台移动。如何让玩家随平台移动?

这是 PlatformPath1 的代码

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

public class FollowPath : MonoBehaviour
{
    public enum FollowType
    {
        MoveTowards,
        Lerp
    }

    public FollowType Type = FollowType.MoveTowards;
    public PathDefinition Path;
    public float Speed = 1;
    public float MaxDistanceToGoal = .1f;

    private IEnumerator<Transform> _currentPoint;

    public void Start()
    {
        if (Path == null)
        {
            Debug.LogError("Path cannot be null", gameObject);
            return;
        }

        _currentPoint = Path.GetPathEnumerator();
        _currentPoint.MoveNext();

        if (_currentPoint.Current == null)
            return;

        transform.position = _currentPoint.Current.position;
    }

    public void Update()
    {
        if (_currentPoint == null || _currentPoint.Current == null)
            return;

        if (Type == FollowType.MoveTowards)
            transform.position = Vector3.MoveTowards (transform.position, _currentPoint.Current.position, Time.deltaTime * Speed);
        else if (Type == FollowType.Lerp)
            transform.position = Vector3.Lerp(transform.position, _currentPoint.Current.position, Time.deltaTime * Speed);

        var distanceSquared = (transform.position - _currentPoint.Current.position).sqrMagnitude;
        if (distanceSquared < MaxDistanceToGoal * MaxDistanceToGoal)
            _currentPoint.MoveNext();
    }
}

这是平台的代码

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

public class PathDefinition : MonoBehaviour
{
    public Transform[] Points;

    public IEnumerator<Transform> GetPathEnumerator()
    {
        if(Points == null || Points.Length < 1)
            yield break;

        var direction = 1;
        var index = 0;
        while (true)
        {
            yield return Points[index];

            if (Points.Length == 1)
                continue;

            if (index <= 0)
                direction = 1;
            else if (index >= Points.Length - 1)
                direction = -1;

            index = index + direction;
        }
    }

    public void OnDrawGizmos()
    {
        if (Points == null || Points.Length < 2)
            return;

        for (var i = 1; i < Points.Length; i++) {
            Gizmos.DrawLine (Points [i - 1].position, Points [i].position);
        }
    }
}
4

3 回答 3

2

您可以将播放器作为孩子添加到平台。这样,当平台移动时,玩家也会移动。
在运动结束时(或在某些用户输入时),您可以中断育儿。这是您可以尝试的一些代码。

public GameObject platform; //The platform Game Object
public GameObject player;   //The player Game Object

//Call this to have the player parented to the platform.
//So, say for example, you have a trigger that the player steps on 
//to activate the platform, you can call this method then
void AttachPlayerToPlatform () {
    player.transform.parent = platform.transform;
}

//Use this method alternatively, if you wish to specify which 
//platform the player Game Object needs to attach to (more useful)
void AttachPlayerToPlatform (GameObject platformToAttachTo) {
    player.transform.parent = platformToAttachTo.transform;
}

//Call this to detach the player from the platform
//This can be used say at the end of the platform's movement
void DetachPlayerFromPlatform () {
    player.transform.parent = null;
}
于 2014-12-31T10:51:44.793 回答
1

如果你站在现实世界中一个移动的平台上,你会随着平台移动的原因是因为平台和你的脚之间的摩擦。如果平台被冰覆盖,当您在平台上时平台开始运动,您可能无法随平台一起移动!

现在我们可以在你的游戏物理中实现它。通常,当您不尝试走路时,您的摩擦力可能只会将您的播放器减速到零速度。相反,您可以在撞击时检查地面对撞机,以查看它是否具有移动平台脚本,并获取平台的速度。然后将此速度用作运动计算的“零点”。

于 2015-01-05T21:06:12.617 回答
1

我认为这会很困难,但实际上我发现制作一个看起来效果很好的解决方案非常简单。

我游戏中的角色有一个 Box Collider。它不是触发器,也不使用物理材料。它有一个刚体,质量为 1,阻力为 0,角阻力为 0.05,使用重力,不是运动学的,不插值,碰撞检测是离散的。它没有约束。对于横向移动,我使用transform.Translate,对于跳跃,我使用 Rigidbody's AddForcewithForceMode.VelocityChange作为最后一个参数。

移动平台还有一个 Box Collider。我根据每一帧transform.position的调用结果设置。Vector3.Lerp我在移动平台上也有这个脚本:

void OnCollisionEnter(Collision collision) {
    // Attach the object to this platform, but have them stay where they are in world space.
    collision.transform.SetParent(transform, true);
    Debug.Log("On platform.");
}

void OnCollisionExit(Collision collision) {
    // Detach the object from this platform, but have them stay where they are in world space.
    collision.transform.SetParent(transform.parent, true);
    Debug.Log("Off platform.");
}

就这样。真的,只是脚本中的两行代码声明我正在实现这两个方法,然后每个方法的实际实现都是一行。一开始的所有信息都是为​​了以防碰撞检测在您的项目中实际上没有起作用(我总是忘记规则是什么,什么不被视为碰撞和/或触发器。)

于 2018-02-28T02:54:18.957 回答