您的位置:首页 > 移动开发 > Unity3D

Unity3d 角色穿墙, 或者互插的解决方案

2014-07-31 14:52 218 查看
如果你在Unity里面使用了Rigidbody, 并且勾选了Is Kinematic 想自己通过Transfrom来控制角色的位置的话。那么你一定会碰到如果角色跑动快了,会插入到其他运动的角色或者静止的单位中,比如墙壁,建筑等等。

1:网上的解决方案: (老的解决方案

网上到是有解决方案,不过都太复杂,都需要自己去预判下一步的步长,这个就是以前的没有引擎的老方法,原理就是如果下一步会被碰到就把下一步的位置直接设置到碰撞的边缘,而不是走满那一步。既然说到这里我们就要说一下Unity带来的全新的解决方案,使用球状射线的原理。Unity摘录如下:

2:我的解决方案(球体射线碰撞)

Physics.SphereCast 球体投射

static function SphereCast (origin : Vector3, radius : float, direction : Vector3, out hitInfo : RaycastHit, distance : float = Mathf.Infinity, layerMask : int = kDefaultRaycastLayers) : boolean

Parameters参数

origin
The center of the sphere at the start of the sweep.
在扫描起点的球体中心点。

radius
The radius of the sphere.
球体的半径。

direction
The direction into which to sweep the sphere.
球体扫描的方向

hitInfo
If true is returned, hitInfo will contain more information about where the collider was hit (See Also: RaycastHit).
如果返回true,hitInfo将包含碰到器碰撞的更多信息。

distance
The length of the sweep
扫描的长度

layerMask
A Layer mask that is used to selectively ignore colliders when casting a capsule.
根据Layer mask层的不同来忽略碰撞体。

Returns

boolean - True when the capsule sweep intersects any collider, otherwise false.

当胶囊物体投射时与碰撞体相交时,返回真,否则返回假。

原理: 把你的角色当成一个球型包围的物体,以他为中心,像一个球体发射射线,如果射线检查到碰撞体那么就认为碰撞了,然后就该处理你自己的逻辑,比如让角色停止,反弹,等等。以下是我在游戏中用到的

//0.7米处有碰撞急停
void Update ()
{
RaycastHit hit;
Vector3 p1 = transform.position;
Vector3 p2 = p1 + Vector3.forward * 0.5f;
if(Physics.CapsuleCast(p1, p2, 0.0f, transform.forward, out hit, 0.2f))
{
//停止该角色
CActionControl.Instance().OnStopMove(uqid_);
}
}


3:说一说当初实现的方案以及为什么不行

最初想法是MonoBehaviour.OnCollisionEnter 使用这个接口来检测碰撞,但是这个接口只会检测出你碰撞的瞬间。也就是说你碰撞提接触的瞬间,但是并不会保证你没有在碰撞了。也就是说MonoBehaviour.OnCollisionStay状态可能一直存在,那么你下次就无法检测是否碰撞了,甚至到后来可能会两个角色都合体了。

也并不是说这个方案实现不了,但是会非常的复杂,比如你想反弹,当两个角色发生了MonoBehaviour.OnCollisionEnter的时候就按照碰撞方向的反方向进行反弹操作,具体的反弹代码只能自己去实现了(由于你是自己控制的Transfrom),而且如果对象多了的话可能会导致,对象像荡秋千一样弹过去了又弹过来。所以这里避免了这种情况,表示这种实现方案在游戏中很难做到!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐