所有效果均都参考使用:https://www.zhihu.com/question/39781696 ,包括同作者(Xylt)聊天得知。
前言:刚遇到这个功能,想的其实挺简单,但是做的时候发现其实我想的有点多并且有些问题。
第一版我用的我自己的思路去做的,不使用物理碰撞利用Transform来判断,判断方向和距离。只要As -> Bn的距离等于An->Bs的距离则为异极相吸,反则排斥。但是他会有一个问题,当两磁铁其中有一个具有旋转,不是水平的那么他的距离就会出现不等的问题。这个点始终想不明白。于是有了第二版。
第二版,通过参考文章,我做出来了。大概想法是,在磁铁的两极添加碰撞,并在脚本中赋予两极不同的标识,通过碰撞进行判断,从而达到相吸或者排斥的条件。移动方式使用物理方式进行操作。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Magnet : MonoBehaviour
{
//最大距离
[SerializeField]
float MaxDistance;
//最远距离
[SerializeField]
float MinDistance;
//最大的力度
[SerializeField]
float MaxForce;
//磁极标识
[SerializeField]
ItemType _Type;
//动画曲线,用来做磁力的变化
public AnimationCurve forceCurve;
Rigidbody thisRig;
public ItemType mType
{
get
{
return _Type;
}
}
private void Awake()
{
thisRig = GetComponentInParent<Rigidbody>();
}
private void OnTriggerStay(Collider other)
{
Magnet script = other.GetComponent<Magnet>();
if (script == null)
return;
Rigidbody otherRig = other.attachedRigidbody;
//获取两极之间的距离
float distance = Mathf.Max(MinDistance, Vector3.Distance(this.transform.position, script.transform.position));
//根据距离获取当前力度
float forceAmount = Mathf.Min(GetForce(distance), MaxForce);
//获取方向
Vector3 forceDir = Vector3.Normalize(this.transform.position - script.transform.position);
//方向以及力度
Vector3 force = forceDir * forceAmount;
//如果同极反方向运动
if (script.mType == this.mType)
force *= -1;
//因为都是磁铁所以需要给产生碰撞的两极都添加力
otherRig.AddForceAtPosition(force, script.transform.position);
if (thisRig != null)
thisRig.AddForceAtPosition(-force, script.transform.position);
}
//利用动画曲线对磁力度进行获取,根据两极之前的距离变大或变小。
float GetForce(float value)
{
float var = value / MaxDistance;
float curveValue = forceCurve.Evaluate(var);
float farce = MaxForce * curveValue;
return farce;
}
}
public enum ItemType
{
South,
North,
}
将这个脚本添加到磁铁的两级然后就可以实现磁体的效果了。需要注意的是磁极的碰撞大小以及位置需要测试调节才能达到效果。
如果,运行过程中出现同级吸引之后不会停止而是来回动作,或者排斥时物体不会停止时,请修改物理系统参数,
- 将相关物体的碰撞检测方式设为:CountinuousDynamic;
-
在ProjectSettings的Physics一栏中,打开Enable Adaptive Force,提高Default Solver Iterations
-
限制磁力最大值
-
减少相关物体的碰撞大小
写个Bug呢是我处理的时候出现的问题,然后去询问的原作者,原作者告知的。感谢!!!!!!!!