您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
131 行
4.2 KiB
131 行
4.2 KiB
using NaughtyAttributes;
|
|
using UnityEngine;
|
|
|
|
namespace GameplayIngredients.Rigs
|
|
{
|
|
[AddComponentMenu(ComponentMenu.rigsPath + "RigidBody Force Rig")]
|
|
[RequireComponent(typeof(Rigidbody))]
|
|
public class RigidBodyForceRig : Rig
|
|
{
|
|
public override int defaultPriority => 0;
|
|
public override UpdateMode defaultUpdateMode => UpdateMode.Update;
|
|
|
|
private Rigidbody m_RigidBody;
|
|
|
|
public enum EffectorType
|
|
{
|
|
Force,
|
|
ForceAtPosition,
|
|
RelativeForce,
|
|
Torque,
|
|
RelativeTorque,
|
|
Explosion
|
|
}
|
|
|
|
[BoxGroup("Configuration"), Tooltip("The kind of force to apply")]
|
|
public EffectorType type;
|
|
[BoxGroup("Configuration"), Tooltip("How to compute the force applied every frame")]
|
|
public ForceMode forceMode;
|
|
|
|
[BoxGroup("Force Properties"),Tooltip("The force or torque vector"), ShowIf("isNotExplosion")]
|
|
public Vector3 vector;
|
|
[BoxGroup("Force Properties"), Tooltip("The force or explosion position"), ShowIf("needPosition")]
|
|
public Vector3 position;
|
|
[BoxGroup("Force Properties"), Tooltip("The force scale over time")]
|
|
public AnimationCurve ForceOverTime = new AnimationCurve(new Keyframe(0, 1), new Keyframe(1, 1));
|
|
|
|
[BoxGroup("Force Properties"), ShowIf("isExplosion")]
|
|
public float explosionForce;
|
|
[BoxGroup("Force Properties"), ShowIf("isExplosion")]
|
|
public float explosionRadius;
|
|
[BoxGroup("Force Properties"), ShowIf("isExplosion")]
|
|
public float upwardsModifier;
|
|
|
|
[BoxGroup("Noise")]
|
|
public bool AddNoise = false;
|
|
[BoxGroup("Noise")]
|
|
public Vector3 NoiseScale = Vector3.one;
|
|
|
|
private float m_Time;
|
|
[SerializeField]
|
|
private float m_RandomSeed;
|
|
|
|
private void Start()
|
|
{
|
|
m_RandomSeed = Random.Range(-100, +100);
|
|
}
|
|
|
|
bool needPosition()
|
|
{
|
|
return type == EffectorType.ForceAtPosition || type == EffectorType.Explosion;
|
|
}
|
|
|
|
bool isExplosion()
|
|
{
|
|
return type == EffectorType.Explosion;
|
|
}
|
|
|
|
bool isNotExplosion()
|
|
{
|
|
return !isExplosion();
|
|
}
|
|
|
|
protected override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
m_RigidBody = GetComponent<Rigidbody>();
|
|
m_Time = 0.0f;
|
|
}
|
|
|
|
Vector3 GetNoise()
|
|
{
|
|
var noise = new Vector3(
|
|
Mathf.PerlinNoise(m_RandomSeed - 11.42f, m_Time + m_RandomSeed + 24.71f),
|
|
Mathf.PerlinNoise(m_RandomSeed + 17.3f, m_Time + m_RandomSeed - 1.08f),
|
|
Mathf.PerlinNoise(m_RandomSeed - 0.07f, m_Time + m_RandomSeed + 43.12f)
|
|
) * 2.0f-Vector3.one;
|
|
noise.Scale(NoiseScale);
|
|
return noise;
|
|
}
|
|
|
|
public override void UpdateRig(float deltaTime)
|
|
{
|
|
if (m_RigidBody == null)
|
|
return;
|
|
|
|
m_Time += deltaTime;
|
|
|
|
Vector3 force = vector;
|
|
float attenuation = ForceOverTime.Evaluate(m_Time);
|
|
if(AddNoise)
|
|
{
|
|
force += GetNoise();
|
|
}
|
|
force *= attenuation;
|
|
|
|
switch (type)
|
|
{
|
|
default:
|
|
case EffectorType.Force:
|
|
m_RigidBody.AddForce(force, forceMode);
|
|
break;
|
|
case EffectorType.ForceAtPosition:
|
|
m_RigidBody.AddForceAtPosition(force, position, forceMode);
|
|
break;
|
|
case EffectorType.RelativeForce:
|
|
m_RigidBody.AddRelativeForce(force, forceMode);
|
|
break;
|
|
case EffectorType.Torque:
|
|
m_RigidBody.AddTorque(force, forceMode);
|
|
break;
|
|
case EffectorType.RelativeTorque:
|
|
m_RigidBody.AddRelativeTorque(force, forceMode);
|
|
break;
|
|
case EffectorType.Explosion:
|
|
m_RigidBody.AddExplosionForce(explosionForce * attenuation, position, explosionRadius, upwardsModifier, forceMode);
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|