C# 待在移动的平台上
我正在Unity中编写一个2D平台,我试图让玩家停留在一个移动的平台上。我已经做了一两天的搜索和修补工作了,我一点运气都没有 基本上,我被告知,当角色触摸时,要尽量让角色随平台移动。 首先,如果我使用与OnTiggerEnter()相关的任何内容,则播放器将直接通过平台。如果我使用OnCollisionCenter()(播放器上有一个CharacterController,平台上有一个BoxCollider),什么都不会发生。我发现这两件事最能说明问题。另一种是用平台来养育玩家,但这显然会导致“问题”(经常提到,从未解释过) 那么,我怎样才能让玩家留在移动平台上呢?以下是移动平台的代码:C# 待在移动的平台上,c#,unity3d,C#,Unity3d,我正在Unity中编写一个2D平台,我试图让玩家停留在一个移动的平台上。我已经做了一两天的搜索和修补工作了,我一点运气都没有 基本上,我被告知,当角色触摸时,要尽量让角色随平台移动。 首先,如果我使用与OnTiggerEnter()相关的任何内容,则播放器将直接通过平台。如果我使用OnCollisionCenter()(播放器上有一个CharacterController,平台上有一个BoxCollider),什么都不会发生。我发现这两件事最能说明问题。另一种是用平台来养育玩家,但这显然会导致“
public class MovingPlatform : MonoBehaviour
{
private float useSpeed;
public float directionSpeed = 9.0f;
float origY;
public float distance = 10.0f;
// Use this for initialization
void Start ()
{
origY = transform.position.y;
useSpeed = -directionSpeed;
}
// Update is called once per frame
void Update ()
{
if(origY - transform.position.y > distance)
{
useSpeed = directionSpeed; //flip direction
}
else if(origY - transform.position.y < -distance)
{
useSpeed = -directionSpeed; //flip direction
}
transform.Translate(0,useSpeed*Time.deltaTime,0);
}
公共类移动平台:MonoBehavior
{
私人浮动速度;
公共浮动方向速度=9.0f;
浮雕;
公共浮动距离=10.0f;
//用于初始化
无效开始()
{
origY=变换位置y;
使用速度=-方向速度;
}
//每帧调用一次更新
无效更新()
{
if(origY-transform.position.y>距离)
{
useSpeed=directionSpeed;//反向
}
else if(原点-变换位置y<-距离)
{
useSpeed=-directionSpeed;//反向
}
transform.Translate(0,useSpeed*Time.deltaTime,0);
}
以下是玩家移动的代码(更新中):
CharacterController=GetComponent();
浮动旋转=输入。GetAxis(“水平”);
if(controller.isground)
{
设置(旋转,0,0);//移动方向=新矢量3(旋转,0,0);
moveDirection=transform.TransformDirection(moveDirection);
//运行代码
if(Input.GetKey(KeyCode.LeftShift)| | Input.GetKey(KeyCode.RightShift))//检查是否按住shift键
{running=true;}
其他的
{running=false;}
moveDirection*=跑步?跑步速度:步行速度;//设置速度
//跳转码
if(Input.GetButtonDown(“跳转”))
{
//移动方向。y=跳跃高度;
跳跃();
}
}
moveDirection.y-=重力*时间增量;
控制器移动(移动方向*时间增量);
编辑:我认为这可能与我如何定义玩家和平台有关,但我尝试了不同的组合。如果平台是触发器(在其碰撞器上)如果不是,我就不能使用OnTigger函数。我有一个刚体连接到播放器和平台上,但它似乎不会影响任何东西。当玩家在某些设置中进入平台时,他会感到紧张,经常会失败。这不是最好的方法,但你可以ld执行从播放机到移动平台的光线投射。如果光线投射点击“移动平台”,您可以检查Y轴上的差异,以确定播放机是否足够靠近它,从而被视为“在平台上”。然后您可以正常调整播放机的位置 例如:
private bool isOnMovingPlatform;
private float offsetToKeepPlayerAbovePlatform = 2.2f;
private float min = 0.2f;
private float max = 1.2f;
private void Update()
{
RaycastHit hit;
if(Physics.Raycast (player.position, player.TransformDirection(Vector3.down), out hit))
{
if(hit.transform.name.Contains("MovingPlatform"))
{
Transform movingPlatform = hit.collider.transform;
if(movingPlatform.position.y - player.position.y <= min && movingPlatform.position.y - player.position.y >= max)
{
isOnMovingPlatform = true;
}
else
{
isOnMovingPlatform = false;
}
}
if(isOnMovingPlatform)
{
player.position = new Vector3(hit.transform.x, hit.transform.y + offsetToKeepPlayerAbovePlatform, 0);
}
}
}
private bool isonmoving平台;
私人浮动OffsetTokeEPlayerOpovePlatform=2.2f;
私人浮动最小值=0.2f;
私人浮动最大值=1.2f;
私有void更新()
{
雷卡斯特击中;
如果(物理.光线投射(玩家.位置,玩家.变换方向(矢量3.向下),出击))
{
if(hit.transform.name.Contains(“移动平台”))
{
Transform movingPlatform=hit.collider.Transform;
if(移动平台.position.y-播放器.position.y=max)
{
isOnMovingPlatform=true;
}
其他的
{
isOnMovingPlatform=false;
}
}
if(isOnMovingPlatform)
{
player.position=new Vector3(hit.transform.x,hit.transform.y+offsetokeepplayerplayeravoveplatform,0);
}
}
}
您需要的似乎是平台上的第二台对撞机。主对撞机具有isTrigger=false
以确保您的角色控制器工作。第二台对撞机使用isTrigger=true
运行,其唯一功能是在OnTriggerInter时检测播放器是否连接到平台e> 调用并将平台留在OnTriggerExit
上
因为你不能有两个相同类型的碰撞器(我想你需要盒子碰撞器),在你的平台游戏对象下构建一个空的子对象,并为其分配框碰撞器。我通常使用一种称为ActionMaterial的特殊物理材料来清理我的东西。如果你使用层并调整了碰撞矩阵,请确保你的碰撞由physX处理。可能会有所帮助。你也可以简单地制作pla玩家的游戏对象变换父对象与平台的变换相等。这允许玩家在平台上时仍然保持移动。至于检测,光线投射有点慢,但可以完成任务。我们通过使用滑动连接2D解决了问题,并在移动平台上将角色的重力比例设置为零。下面是t他与完整的解释联系在一起:
我从未使用过Unity3D,但当角色在平台上时,是否可以执行类似于平台上移动方向的操作?我尝试过,但我似乎遇到了OnTrigger和OnCollision函数的问题,这将导致“玩家在平台上时”的问题部分原因。我认为这与我如何定义我的对象有关,但我不确定如何正确定义它们,这样才能起作用。此外,你需要确保角色的moveDirection.y永远不小于平台的moveDirection.y,否则你会失败(除非Unity3D框架自动为您处理此问题?)不幸的是,Unity似乎无法独立完成此任务,因此我正试图与之抗争,以使玩家继续留在游戏中。我将继续
private bool isOnMovingPlatform;
private float offsetToKeepPlayerAbovePlatform = 2.2f;
private float min = 0.2f;
private float max = 1.2f;
private void Update()
{
RaycastHit hit;
if(Physics.Raycast (player.position, player.TransformDirection(Vector3.down), out hit))
{
if(hit.transform.name.Contains("MovingPlatform"))
{
Transform movingPlatform = hit.collider.transform;
if(movingPlatform.position.y - player.position.y <= min && movingPlatform.position.y - player.position.y >= max)
{
isOnMovingPlatform = true;
}
else
{
isOnMovingPlatform = false;
}
}
if(isOnMovingPlatform)
{
player.position = new Vector3(hit.transform.x, hit.transform.y + offsetToKeepPlayerAbovePlatform, 0);
}
}
}