Update
This commit is contained in:
@@ -1,119 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Items.Actions;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The MagicParticle will perform a MagicItem impact when it collides with an object. In order for this to work correctly the ParticleSystem must
|
||||
/// have collisions enabled and the "Send Collision Event" parameter enabled. See this page for more information:
|
||||
/// https://docs.unity3d.com/Manual/PartSysCollisionModule.html.
|
||||
/// </summary>
|
||||
public class MagicParticle : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Can the particle collide with the originator?")]
|
||||
[SerializeField] protected bool m_CanCollideWithOriginator = false;
|
||||
|
||||
private GameObject m_GameObject;
|
||||
private Transform m_Transform;
|
||||
private MagicItem m_MagicItem;
|
||||
private uint m_CastID;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
private void Awake()
|
||||
{
|
||||
m_GameObject = gameObject;
|
||||
m_Transform = transform;
|
||||
|
||||
var particleSystem = GetComponent<ParticleSystem>();
|
||||
if (particleSystem == null) {
|
||||
Debug.LogError($"Error: The MagicProjectile {m_GameObject.name} does not have a ParticleSystem attached.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!particleSystem.collision.enabled) {
|
||||
Debug.LogError($"Error: The collision module on the MagicProjectile {m_GameObject.name} is disabled. This should be enabled in order to receive collision events.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!particleSystem.collision.sendCollisionMessages) {
|
||||
Debug.LogError($"Error: Send Collision Messages on the the MagicProjectile {m_GameObject.name} is disabled. This should be enabled in order to receive collision events.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the particle to the specified MagicItem.
|
||||
/// </summary>
|
||||
/// <param name="magicItem">The MagicItem that casted the particle.</param>
|
||||
/// <param name="castID">The ID of the MagicItem cast.</param>
|
||||
public void Initialize(MagicItem magicItem, uint castID)
|
||||
{
|
||||
m_MagicItem = magicItem;
|
||||
m_CastID = castID;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A particle has collided with another object.
|
||||
/// </summary>
|
||||
/// <param name="other">The object that the particle collided with.</param>
|
||||
public void OnParticleCollision(GameObject other)
|
||||
{
|
||||
// If the transform is null the particle hasn't been initialized yet.
|
||||
if (m_Transform == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent the particle from colliding with the originator.
|
||||
if (!m_CanCollideWithOriginator) {
|
||||
var characterLocomotion = other.GetCachedComponent<Character.UltimateCharacterLocomotion>();
|
||||
if (characterLocomotion != null && m_MagicItem.Character == characterLocomotion.gameObject) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// PerformImpact requires a RaycastHit.
|
||||
var colliders = other.GetCachedComponents<Collider>();
|
||||
if (colliders == null) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < colliders.Length; ++i) {
|
||||
if (colliders[i].isTrigger) {
|
||||
continue;
|
||||
}
|
||||
Vector3 closestPoint;
|
||||
if (colliders[i] is BoxCollider || colliders[i] is SphereCollider || colliders[i] is CapsuleCollider || (colliders[i] is MeshCollider && (colliders[i] as MeshCollider).convex)) {
|
||||
closestPoint = colliders[i].ClosestPoint(m_Transform.position);
|
||||
} else {
|
||||
closestPoint = m_Transform.position;
|
||||
}
|
||||
var direction = other.transform.position - closestPoint;
|
||||
if (Physics.Raycast(closestPoint - direction.normalized * 0.1f, direction.normalized, out var hit, direction.magnitude + 0.1f, 1 << other.layer)) {
|
||||
m_MagicItem.PerformImpact(m_CastID, m_GameObject, other, hit);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The particle has been disabled.
|
||||
/// </summary>
|
||||
private void OnDisable()
|
||||
{
|
||||
// All of the impact actions should be reset for the particle spawn id.
|
||||
if (m_MagicItem != null && m_MagicItem.ImpactActions != null) {
|
||||
for (int i = 0; i < m_MagicItem.ImpactActions.Length; ++i) {
|
||||
m_MagicItem.ImpactActions[i].Reset(m_CastID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6db731486d10934cbfa28dc65e38c1a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,106 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Items.Actions;
|
||||
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
|
||||
using Opsive.UltimateCharacterController.Networking.Game;
|
||||
#endif
|
||||
using Opsive.UltimateCharacterController.Objects;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The ParticleProjectile extends TrajectoryObject and notifies the MagicItem when the object has collided with another object.
|
||||
/// TrajectoryObject.CollisionMode should be set to Ignore for the projectile to pass through the object.
|
||||
/// </summary>
|
||||
public class MagicProjectile : TrajectoryObject
|
||||
{
|
||||
[Tooltip("Should the projectile be destroyed when there's a collision?")]
|
||||
[SerializeField] protected bool m_DestroyOnCollision;
|
||||
[Tooltip("Should the projectile be destroyed after the particle has stopped emitting?")]
|
||||
[SerializeField] protected bool m_WaitForParticleStop;
|
||||
|
||||
public bool DestroyOnCollision { get { return m_DestroyOnCollision; } set { m_DestroyOnCollision = value; } }
|
||||
public bool WaitForParticleStop { get { return m_WaitForParticleStop; } set { m_WaitForParticleStop = value; } }
|
||||
|
||||
protected MagicItem m_MagicItem;
|
||||
protected uint m_CastID;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the object with the specified velocity and torque.
|
||||
/// </summary>
|
||||
/// <param name="velocity">The starting velocity.</param>
|
||||
/// <param name="torque">The starting torque.</param>
|
||||
/// <param name="originator">The object that instantiated the trajectory object.</param>
|
||||
/// <param name="magicItem">The MagicItem that created the projectile.</param>
|
||||
/// <param name="castID">The ID of the cast.</param>
|
||||
public void Initialize(Vector3 velocity, Vector3 torque, GameObject originator, MagicItem magicItem, uint castID)
|
||||
{
|
||||
m_MagicItem = magicItem;
|
||||
m_CastID = castID;
|
||||
|
||||
Initialize(velocity, torque, originator);
|
||||
if (m_Collider != null) {
|
||||
m_Collider.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has collided with another object.
|
||||
/// </summary>
|
||||
/// <param name="hit">The RaycastHit of the object. Can be null.</param>
|
||||
protected override void OnCollision(RaycastHit? hit)
|
||||
{
|
||||
base.OnCollision(hit);
|
||||
|
||||
if (!hit.HasValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_MagicItem.PerformImpact(m_CastID, m_GameObject, hit.Value.transform.gameObject, hit.Value);
|
||||
|
||||
// Destroys the projectile when it has collided with an object.
|
||||
if (m_DestroyOnCollision) {
|
||||
// The projectile can wait for any particles to stop emitting.
|
||||
var immediateDestroy = !m_WaitForParticleStop;
|
||||
if (!immediateDestroy) {
|
||||
var particleSystem = m_GameObject.GetCachedComponent<ParticleSystem>();
|
||||
if (particleSystem != null) {
|
||||
particleSystem.Stop(true, ParticleSystemStopBehavior.StopEmitting);
|
||||
Scheduler.Schedule(particleSystem.main.duration, ReturnToObjectPool);
|
||||
immediateDestroy = false;
|
||||
}
|
||||
}
|
||||
if (immediateDestroy) {
|
||||
ReturnToObjectPool();
|
||||
} else {
|
||||
// The projectile is waiting on the particles to be destroyed. Stop moving.
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the projectile back to the object pool.
|
||||
/// </summary>
|
||||
private void ReturnToObjectPool()
|
||||
{
|
||||
#if ULTIMATE_CHARACTER_CONTROLLER_MULTIPLAYER
|
||||
if (NetworkObjectPool.IsNetworkActive()) {
|
||||
// The object may have already been destroyed over the network.
|
||||
if (!m_GameObject.activeSelf) {
|
||||
return;
|
||||
}
|
||||
NetworkObjectPool.Destroy(m_GameObject);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
ObjectPool.Destroy(m_GameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9a93ab405fbc6e54db16c521de2c6cc5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,21 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies an offset for the pivot position.
|
||||
/// </summary>
|
||||
public class PivotOffset : MonoBehaviour
|
||||
{
|
||||
[Tooltip("The pivot offset.")]
|
||||
[SerializeField] protected Vector3 m_Offset;
|
||||
|
||||
public Vector3 Offset { get { return m_Offset; } set { m_Offset = value; } }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a16c458321536b43b2e57119a8cb244
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,17 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies that the attached object should cause recoil when hit with a MeleeWeapon.
|
||||
/// </summary>
|
||||
public class RecoilObject : MonoBehaviour
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa25a7ec2cbec8a40988d4328115db41
|
||||
timeCreated: 1532978512
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,89 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using Opsive.Shared.Game;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a shell casing which uses the trajectory object for kinematic shell movement.
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody))]
|
||||
public class Shell : TrajectoryObject
|
||||
{
|
||||
[Tooltip("Time to live in seconds before the shell is removed.")]
|
||||
[SerializeField] protected float m_Lifespan = 10;
|
||||
[Tooltip("Chance of shell not being removed after settling on the ground.")]
|
||||
[Range(0, 1)] [SerializeField] protected float m_Persistence = 1;
|
||||
|
||||
private float m_RemoveTime;
|
||||
private Vector3 m_StartScale;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_StartScale = transform.localScale;
|
||||
|
||||
// The Rigidbody is only used to notify Unity that the object isn't static. The Rigidbody doesn't control any movement.
|
||||
var rigidbody = GetComponent<Rigidbody>();
|
||||
rigidbody.mass = m_Mass;
|
||||
rigidbody.isKinematic = true;
|
||||
rigidbody.constraints = RigidbodyConstraints.FreezeAll;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The shell has been spawned - reset the timing and component values.
|
||||
/// </summary>
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
|
||||
m_RemoveTime = Time.time + m_Lifespan;
|
||||
m_Transform.localScale = m_StartScale;
|
||||
|
||||
if (m_Collider != null) {
|
||||
m_Collider.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move and rotate the object according to a parabolic trajectory.
|
||||
/// </summary>
|
||||
protected override void FixedUpdate()
|
||||
{
|
||||
base.FixedUpdate();
|
||||
|
||||
if (Time.time > m_RemoveTime) { // The shell should be removed.
|
||||
m_Transform.localScale = Vector3.Lerp(m_Transform.localScale, Vector3.zero, Utility.TimeUtility.FramerateDeltaTime * 0.2f);
|
||||
if (Time.time > m_RemoveTime + 0.5f) {
|
||||
ObjectPool.Destroy(m_GameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has collided with another object.
|
||||
/// </summary>
|
||||
/// <param name="hit">The RaycastHit of the object. Can be null.</param>
|
||||
protected override void OnCollision(RaycastHit? hit)
|
||||
{
|
||||
base.OnCollision(hit);
|
||||
|
||||
if (m_Velocity.sqrMagnitude > 4) { // Hard bounce.
|
||||
// Apply more random rotation velocity to make the shell behave a bit unpredictably on a hard bounce (similar to real brass shell behavior).
|
||||
AddTorque(Random.rotation.eulerAngles * 0.15f * (Random.value > 0.5f ? 1 : -1));
|
||||
} else if (Random.value > m_Persistence) { // Soft bounce.
|
||||
// Remove the shell after half a second on a soft bounce.
|
||||
m_RemoveTime = Time.time + 0.5f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec2d29bda368ada499ad37e3d0781339
|
||||
timeCreated: 1505688289
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,63 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.UltimateCharacterController.Items.Actions;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The ShieldCollider component specifies the object that acts as a collider for the shield.
|
||||
/// </summary>
|
||||
public class ShieldCollider : MonoBehaviour
|
||||
{
|
||||
[Tooltip("A reference to the Shield item action.")]
|
||||
[SerializeField] protected Shield m_Shield;
|
||||
[Tooltip("Is the collider attached to a Shield used for the first person perspective?")]
|
||||
[HideInInspector] [SerializeField] protected bool m_FirstPersonPerspective;
|
||||
|
||||
[Shared.Utility.NonSerialized] public Shield Shield { get { return m_Shield; } set { m_Shield = value; } }
|
||||
[Shared.Utility.NonSerialized] public bool FirstPersonPerspective { set { m_FirstPersonPerspective = value; } }
|
||||
|
||||
private Collider m_Collider;
|
||||
private GameObject m_Character;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
private void Awake()
|
||||
{
|
||||
if (m_Shield == null) {
|
||||
Debug.LogError("Error: The shield is not assigned. Ensure the shield is created from the Item Manager.", this);
|
||||
return;
|
||||
}
|
||||
m_Collider = GetComponent<Collider>();
|
||||
m_Collider.enabled = false;
|
||||
|
||||
m_Character = m_Shield.gameObject.GetComponentInParent<Character.UltimateCharacterLocomotion>().gameObject;
|
||||
EventHandler.RegisterEvent<bool>(m_Character, "OnCharacterChangePerspectives", OnChangePerspectives);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The camera perspective between first and third person has changed.
|
||||
/// </summary>
|
||||
/// <param name="inFirstPerson">Is the camera in a first person view?</param>
|
||||
private void OnChangePerspectives(bool firstPersonPerspective)
|
||||
{
|
||||
// The collider should only be enabled for the corresponding perspective.
|
||||
m_Collider.enabled = m_FirstPersonPerspective == firstPersonPerspective;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has been destroyed.
|
||||
/// </summary>
|
||||
private void OnDestroy()
|
||||
{
|
||||
EventHandler.UnregisterEvent<bool>(m_Character, "OnCharacterChangePerspectives", OnChangePerspectives);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16cb3bccd7b264c46ba4804f977c18b9
|
||||
timeCreated: 1534209342
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,124 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using Opsive.Shared.Events;
|
||||
using Opsive.Shared.Game;
|
||||
using Opsive.UltimateCharacterController.Character;
|
||||
using Opsive.UltimateCharacterController.Game;
|
||||
using Opsive.UltimateCharacterController.Items;
|
||||
using Opsive.UltimateCharacterController.Items.Actions.PerspectiveProperties;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The Smoke component is attached to a GameObject with the a ParticleSystem attached representing smoke.
|
||||
/// </summary>
|
||||
public class Smoke : MonoBehaviour
|
||||
{
|
||||
private GameObject m_GameObject;
|
||||
private Transform m_Transform;
|
||||
private Item m_Item;
|
||||
private int m_ItemActionID;
|
||||
private ParticleSystem[] m_Particles;
|
||||
private ParticleSystemSimulationSpace[] m_SimulationSpace;
|
||||
|
||||
private GameObject m_Character;
|
||||
private int m_StartLayer;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
private void Awake()
|
||||
{
|
||||
m_GameObject = gameObject;
|
||||
m_Transform = transform;
|
||||
m_Particles = GetComponentsInChildren<ParticleSystem>();
|
||||
m_SimulationSpace = new ParticleSystemSimulationSpace[m_Particles.Length];
|
||||
m_StartLayer = m_GameObject.layer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A weapon has been fired and the smoke needs to show.
|
||||
/// </summary>
|
||||
/// <param name="item">The item that the muzzle flash is attached to.</param>
|
||||
/// <param name="itemActionID">The ID which corresponds to the ItemAction that spawned the smoke.</param>
|
||||
/// <param name="characterLocomotion">The character that the smoke is attached to.</param>
|
||||
public void Show(Item item, int itemActionID, UltimateCharacterLocomotion characterLocomotion)
|
||||
{
|
||||
m_Character = characterLocomotion.gameObject;
|
||||
EventHandler.RegisterEvent<bool>(m_Character, "OnCharacterChangePerspectives", OnChangePerspectives);
|
||||
|
||||
m_Item = item;
|
||||
m_ItemActionID = itemActionID;
|
||||
m_GameObject.layer = characterLocomotion.FirstPersonPerspective ? LayerManager.Overlay : m_StartLayer;
|
||||
|
||||
// Disable the object after the particles are done playing.
|
||||
float maxLifeTime = 0;
|
||||
for (int i = 0; i < m_Particles.Length; ++i) {
|
||||
m_Particles[i].Play();
|
||||
var lifeTime = 0f;
|
||||
if ((lifeTime = m_Particles[i].main.startLifetime.Evaluate(0)) > maxLifeTime) {
|
||||
maxLifeTime = lifeTime;
|
||||
}
|
||||
}
|
||||
|
||||
Scheduler.Schedule(maxLifeTime, DestroySelf);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Place itself back in the ObjectPool.
|
||||
/// </summary>
|
||||
public void DestroySelf()
|
||||
{
|
||||
ObjectPool.Destroy(m_GameObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The character perspective between first and third person has changed.
|
||||
/// </summary>
|
||||
/// <param name="firstPersonPerspective">Is the character in a first person perspective?</param>
|
||||
private void OnChangePerspectives(bool firstPersonPerspective)
|
||||
{
|
||||
// All of the particles should be set to local space so they'll change correctly when switching perspective.
|
||||
for (int i = 0; i < m_Particles.Length; ++i) {
|
||||
m_SimulationSpace[i] = m_Particles[i].main.simulationSpace;
|
||||
var mainParticle = m_Particles[i].main;
|
||||
mainParticle.simulationSpace = ParticleSystemSimulationSpace.Local;
|
||||
}
|
||||
|
||||
// When switching locations the local position and rotation should remain the same.
|
||||
var localPosition = m_Transform.localPosition;
|
||||
var localRotation = m_Transform.rotation;
|
||||
|
||||
var itemAction = m_Item.ItemActions[m_ItemActionID];
|
||||
var perspectiveProperties = (firstPersonPerspective ? itemAction.FirstPersonPerspectiveProperties : itemAction.ThirdPersonPerspectiveProperties);
|
||||
var smokeLocation = (perspectiveProperties as IShootableWeaponPerspectiveProperties).SmokeLocation;
|
||||
m_Transform.parent = smokeLocation;
|
||||
m_Transform.localPosition = localPosition;
|
||||
m_Transform.rotation = localRotation;
|
||||
|
||||
// Switch the particle simulation space back to the previous value.
|
||||
for (int i = 0; i < m_Particles.Length; ++i) {
|
||||
var mainParticle = m_Particles[i].main;
|
||||
mainParticle.simulationSpace = m_SimulationSpace[i];
|
||||
}
|
||||
|
||||
m_GameObject.layer = firstPersonPerspective ? LayerManager.Overlay : m_StartLayer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object has been disabled.
|
||||
/// </summary>
|
||||
private void OnDisable()
|
||||
{
|
||||
if (m_Character != null) {
|
||||
EventHandler.UnregisterEvent<bool>(m_Character, "OnCharacterChangePerspectives", OnChangePerspectives);
|
||||
}
|
||||
m_Character = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c09be7c342cf2642a12738bb38baaf5
|
||||
timeCreated: 1505602291
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,53 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using Opsive.Shared.Game;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// The tracer will show a Line Renderer from the hitscan fire point to the hit point.
|
||||
/// </summary>
|
||||
public class Tracer : MonoBehaviour
|
||||
{
|
||||
[Tooltip("The amount of time that the tracer is visible for")]
|
||||
[SerializeField] protected float m_VisibleTime = 0.05f;
|
||||
|
||||
// Component references
|
||||
private Transform m_Transform;
|
||||
private LineRenderer m_LineRenderer;
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the default values.
|
||||
/// </summary>
|
||||
private void Awake()
|
||||
{
|
||||
m_Transform = transform;
|
||||
m_LineRenderer = GetComponent<LineRenderer>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the hit point that the tracer should move to.
|
||||
/// </summary>
|
||||
/// <param name="hitPoint">The hit point position.</param>
|
||||
public virtual void Initialize(Vector3 hitPoint)
|
||||
{
|
||||
m_LineRenderer.SetPosition(0, m_Transform.position);
|
||||
m_LineRenderer.SetPosition(1, hitPoint);
|
||||
|
||||
Scheduler.Schedule(m_VisibleTime, DestroyObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Places the object back in the ObjectPool.
|
||||
/// </summary>
|
||||
private void DestroyObject()
|
||||
{
|
||||
ObjectPool.Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27f97a858bca96045a845d9af5c6dba3
|
||||
timeCreated: 1511455046
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,396 +0,0 @@
|
||||
/// ---------------------------------------------
|
||||
/// Ultimate Character Controller
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
|
||||
namespace Opsive.UltimateCharacterController.Objects.ItemAssist
|
||||
{
|
||||
using Opsive.Shared.Game;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Builds a mesh which can show a trail following a melee weapon. This is typically used when the melee weapon is slashed.
|
||||
/// </summary>
|
||||
public class Trail : MonoBehaviour
|
||||
{
|
||||
[Tooltip("The minimum distance between the position of the last slice and the current position.")]
|
||||
[SerializeField] protected float m_MinDistance = 0.01f;
|
||||
[Tooltip("The vertical length of the trail.")]
|
||||
[SerializeField] protected float m_Length = 1f;
|
||||
[Tooltip("The maximum number of slices within the trail. A larger value will cause the trail to be longer.")]
|
||||
[SerializeField] protected int m_MaxSliceCount = 50;
|
||||
[Tooltip("The smoothing value of the curve. A larger value will have a smoother curve compared to a smaller value.")]
|
||||
[SerializeField] protected int m_CurveSmoothness = 10;
|
||||
[Tooltip("The steepness of the curve. A value closer to 1 will increase the steepness.")]
|
||||
[Range(0, 1)] [SerializeField] protected float m_CurveSteepness = 0.5f;
|
||||
[Tooltip("The start color of the trail, near the melee weapon object.")]
|
||||
[SerializeField] protected Color m_StartColor = Color.white;
|
||||
[Tooltip("The end color of the trail.")]
|
||||
[SerializeField] protected Color m_EndColor = Color.white;
|
||||
[Tooltip("The amount of time the slice should be visible.")]
|
||||
[SerializeField] protected float m_VisibilityTime = 1;
|
||||
|
||||
private GameObject m_GameObject;
|
||||
private Transform m_Transform;
|
||||
private Mesh m_Mesh;
|
||||
|
||||
private float m_MinDistanceSquared;
|
||||
private TrailSlice[] m_TrailSlices = new TrailSlice[4];
|
||||
private int m_TrailSlicesIndex = -1;
|
||||
private int m_TrailSlicesCount;
|
||||
|
||||
private TrailSlice[] m_SmoothedTrailSlices;
|
||||
private int m_SmoothedTrailSlicesIndex = -1;
|
||||
private int m_SmoothedTrailSlicesCount;
|
||||
|
||||
private int m_SmoothedTrailSlicesPrevCount;
|
||||
private int m_SmoothedTrailSlicesPrevIndex;
|
||||
|
||||
private List<Vector3> m_Vertices;
|
||||
private List<Vector2> m_UVs;
|
||||
private List<Color> m_Colors;
|
||||
private List<int> m_Triangles;
|
||||
|
||||
private bool m_GenerateSlices;
|
||||
|
||||
/// <summary>
|
||||
/// A small container class for each object that represents a slice from the melee trail.
|
||||
/// </summary>
|
||||
private struct TrailSlice
|
||||
{
|
||||
private Vector3 m_Point;
|
||||
private Vector3 m_Up;
|
||||
private float m_Time;
|
||||
|
||||
public Vector3 Point { get { return m_Point; } }
|
||||
public Vector3 Up { get { return m_Up; } }
|
||||
public float Time { get { return m_Time; } }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the slice.
|
||||
/// </summary>
|
||||
/// <param name="point">The position of the slice.</param>
|
||||
/// <param name="up">The up direction of the slice.</param>
|
||||
public void Initialize(Vector3 point, Vector3 up)
|
||||
{
|
||||
m_Point = point;
|
||||
m_Up = up;
|
||||
m_Time = UnityEngine.Time.time;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the trail.
|
||||
/// </summary>
|
||||
private void Awake()
|
||||
{
|
||||
m_GameObject = gameObject;
|
||||
m_Transform = transform;
|
||||
|
||||
var meshFilter = GetComponent<MeshFilter>();
|
||||
if (meshFilter == null) {
|
||||
Debug.LogError("Error: Unable to find the MeshFilter component. Enssure the Trail object has been created through the Object Manager.");
|
||||
return;
|
||||
}
|
||||
m_Mesh = meshFilter.mesh;
|
||||
|
||||
m_MinDistanceSquared = m_MinDistance * m_MinDistance;
|
||||
var count = m_MaxSliceCount * m_CurveSmoothness;
|
||||
m_SmoothedTrailSlices = new TrailSlice[count];
|
||||
|
||||
m_Vertices = new List<Vector3>(count * 2);
|
||||
m_UVs = new List<Vector2>(count * 2);
|
||||
m_Colors = new List<Color>(count * 2);
|
||||
m_Triangles = new List<int>((count - 1) * 6); // 3 indices per triangle, 2 triangles per slice.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Start to generate the trail slices.
|
||||
/// </summary>
|
||||
private void OnEnable()
|
||||
{
|
||||
m_GenerateSlices = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Samples the position of the melee object.
|
||||
/// </summary>
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (m_GenerateSlices) {
|
||||
SampleTrail();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays the trail.
|
||||
/// </summary>
|
||||
private void LateUpdate()
|
||||
{
|
||||
RemoveOldSlices();
|
||||
BuildMesh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores a new sample of the trail slice.
|
||||
/// </summary>
|
||||
private void SampleTrail()
|
||||
{
|
||||
// Add a new slice if the last sample position is too far away.
|
||||
if (m_TrailSlicesCount == 0 || (m_TrailSlices[m_TrailSlicesIndex].Point - m_Transform.position).sqrMagnitude > m_MinDistanceSquared) {
|
||||
// Revert the trail slice index and smoothed index/count values so the extra slice can be removed. A more accurate slice value will replace the prediction.
|
||||
if (m_TrailSlicesCount > 3) {
|
||||
m_TrailSlicesIndex = m_TrailSlicesIndex - 1;
|
||||
if (m_TrailSlicesIndex < 0) {
|
||||
m_TrailSlicesIndex += m_TrailSlicesCount;
|
||||
}
|
||||
|
||||
m_SmoothedTrailSlicesIndex = m_SmoothedTrailSlicesPrevIndex;
|
||||
m_SmoothedTrailSlicesCount = m_SmoothedTrailSlicesPrevCount;
|
||||
}
|
||||
|
||||
// Add the new slice at the current position.
|
||||
AddTrailSlice(m_Transform.position, m_Transform.up);
|
||||
|
||||
// A catmull-rom curve smooths the middle two verticies rather then all four vertices. Add one more slice near the beginning of the trail so the start of the
|
||||
// curve will intersect with the melee object.
|
||||
if (m_TrailSlicesCount > 3) {
|
||||
var prevIndex = m_TrailSlicesIndex - 1;
|
||||
if (prevIndex < 0) {
|
||||
prevIndex = m_TrailSlicesCount - 1;
|
||||
}
|
||||
var prevTrailSlice = m_TrailSlices[prevIndex];
|
||||
var trailSlice = m_TrailSlices[m_TrailSlicesIndex];
|
||||
|
||||
// Remember the previous smoothed values so the extra slice can be removed.
|
||||
m_SmoothedTrailSlicesPrevIndex = m_SmoothedTrailSlicesIndex;
|
||||
m_SmoothedTrailSlicesPrevCount = m_SmoothedTrailSlicesCount;
|
||||
// The new slice should be in the previous to the current slice position. This value probably won't be correct the next frame unless
|
||||
// the object is moving in a linear path but it is a good prediction.
|
||||
AddTrailSlice(trailSlice.Point + (trailSlice.Point - prevTrailSlice.Point).normalized, (trailSlice.Up + prevTrailSlice.Up) / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the point and up vertex to the trail slices array. The values will also be smoothed.
|
||||
/// </summary>
|
||||
/// <param name="point">The point of the slice.</param>
|
||||
/// <param name="up">The up direction of the slice.</param>
|
||||
private void AddTrailSlice(Vector3 point, Vector3 up)
|
||||
{
|
||||
// Catmull-rom curves do not like repeated points.
|
||||
if (m_TrailSlicesCount > 0 && m_TrailSlices[m_TrailSlicesIndex].Point == point) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_TrailSlicesIndex = (m_TrailSlicesIndex + 1) % m_TrailSlices.Length;
|
||||
m_TrailSlices[m_TrailSlicesIndex].Initialize(point, up);
|
||||
if (m_TrailSlicesIndex + 1 > m_TrailSlicesCount) {
|
||||
m_TrailSlicesCount++;
|
||||
}
|
||||
|
||||
SmoothTrailSlice();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Smooths the trail slices with a catmull-rom curve.
|
||||
/// </summary>
|
||||
private void SmoothTrailSlice()
|
||||
{
|
||||
// A catmull-rom curve requires at least four points.
|
||||
if (m_TrailSlicesCount < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A fixed size array is used to store the vertex values. The starting index may not be at the beginning of the array.
|
||||
var startIndex = m_TrailSlicesIndex - m_TrailSlicesCount + 1;
|
||||
if (startIndex < 0) {
|
||||
startIndex = m_TrailSlices.Length + startIndex;
|
||||
}
|
||||
|
||||
// Determine a smoothed value for both the point and up vertex.
|
||||
var p0 = m_TrailSlices[startIndex].Point;
|
||||
var p1 = m_TrailSlices[(startIndex + 1) % 4].Point;
|
||||
var p2 = m_TrailSlices[(startIndex + 2) % 4].Point;
|
||||
var p3 = m_TrailSlices[(startIndex + 3) % 4].Point;
|
||||
|
||||
var u0 = m_TrailSlices[startIndex].Up;
|
||||
var u1 = m_TrailSlices[(startIndex + 1) % 4].Up;
|
||||
var u2 = m_TrailSlices[(startIndex + 2) % 4].Up;
|
||||
var u3 = m_TrailSlices[(startIndex + 3) % 4].Up;
|
||||
|
||||
var t1 = CentripetralCatmullRomTime(0, p0, p1);
|
||||
var t2 = CentripetralCatmullRomTime(t1, p1, p2);
|
||||
var t3 = CentripetralCatmullRomTime(t2, p2, p3);
|
||||
|
||||
// Iterate based on the number of sample values.
|
||||
var iterAmount = ((t2 - t1) / m_CurveSmoothness);
|
||||
for (float t = t1; t < t2; t += iterAmount) {
|
||||
var point = CentripetralCatmullRomValue(p0, p1, p2, p3, 0, t1, t2, t3, t);
|
||||
var up = CentripetralCatmullRomValue(u0, u1, u2, u3, 0, t1, t2, t3, t);
|
||||
|
||||
// The value has been determined. Add it to the smoothed array.
|
||||
m_SmoothedTrailSlicesIndex = (m_SmoothedTrailSlicesIndex + 1) % m_SmoothedTrailSlices.Length;
|
||||
m_SmoothedTrailSlices[m_SmoothedTrailSlicesIndex].Initialize(point, up);
|
||||
if (m_SmoothedTrailSlicesIndex + 1 > m_SmoothedTrailSlicesCount) {
|
||||
m_SmoothedTrailSlicesCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the time of the centripetral catmull-rom curve, defined in https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_spline.
|
||||
/// </summary>
|
||||
/// <param name="t">The sample time.</param>
|
||||
/// <param name="v0">The first vertex.</param>
|
||||
/// <param name="v1">The second vertex.</param>
|
||||
/// <returns>The time of the centripetral catmull-rom curve.</returns>
|
||||
private float CentripetralCatmullRomTime(float t, Vector3 v0, Vector3 v1)
|
||||
{
|
||||
var a = Mathf.Pow((v1.x - v0.x), 2f) + Mathf.Pow((v1.y - v0.y), 2f) + Mathf.Pow((v1.z - v0.z), 2f);
|
||||
var b = Mathf.Pow(a, 0.5f);
|
||||
var c = Mathf.Pow(b, m_CurveSteepness);
|
||||
|
||||
return c + t;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the vertex of the centripetral catmull-rom curve, defined in https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_spline.
|
||||
/// </summary>
|
||||
/// <returns>The vertex of the centripetral catmull-rom curve.</returns>
|
||||
private Vector3 CentripetralCatmullRomValue(Vector3 v0, Vector3 v1, Vector3 v2, Vector3 v3, float t0, float t1, float t2, float t3, float t)
|
||||
{
|
||||
var a1 = (t1 - t) / (t1 - t0) * v0 + (t - t0) / (t1 - t0) * v1;
|
||||
var a2 = (t2 - t) / (t2 - t1) * v1 + (t - t1) / (t2 - t1) * v2;
|
||||
var a3 = (t3 - t) / (t3 - t2) * v2 + (t - t2) / (t3 - t2) * v3;
|
||||
var b1 = (t2 - t) / (t2 - t0) * a1 + (t - t0) / (t2 - t0) * a2;
|
||||
var b2 = (t3 - t) / (t3 - t1) * a2 + (t - t1) / (t3 - t1) * a3;
|
||||
return (t2 - t) / (t2 - t1) * b1 + (t - t1) / (t2 - t1) * b2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes any slices which have existed for more than the visible time.
|
||||
/// </summary>
|
||||
private void RemoveOldSlices()
|
||||
{
|
||||
if (m_TrailSlicesCount == 0) {
|
||||
if (!m_GenerateSlices) {
|
||||
if (ObjectPool.InstantiatedWithPool(m_GameObject)) {
|
||||
ObjectPool.Destroy(m_GameObject);
|
||||
} else {
|
||||
m_GameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var startIndex = m_TrailSlicesIndex - m_TrailSlicesCount + 1;
|
||||
if (startIndex < 0) {
|
||||
startIndex = m_TrailSlices.Length + startIndex;
|
||||
}
|
||||
var count = m_TrailSlicesCount;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
var trailSlice = m_TrailSlices[(startIndex + i) % m_TrailSlices.Length];
|
||||
if (trailSlice.Time + m_VisibilityTime > Time.time) {
|
||||
break;
|
||||
}
|
||||
|
||||
// The slice has existed for more than the visiblity time - remove it by decreasing the count.
|
||||
m_TrailSlicesCount--;
|
||||
}
|
||||
|
||||
if (m_SmoothedTrailSlicesCount == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
startIndex = m_SmoothedTrailSlicesIndex - m_SmoothedTrailSlicesCount + 1;
|
||||
if (startIndex < 0) {
|
||||
startIndex = m_SmoothedTrailSlices.Length + startIndex;
|
||||
}
|
||||
count = m_SmoothedTrailSlicesCount;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
var trailSlice = m_SmoothedTrailSlices[(startIndex + i) % m_SmoothedTrailSlices.Length];
|
||||
if (trailSlice.Time + m_VisibilityTime > Time.time) {
|
||||
break;
|
||||
}
|
||||
|
||||
// The slice has existed for more than the visiblity time - remove it by decreasing the count.
|
||||
m_SmoothedTrailSlicesCount--;
|
||||
m_SmoothedTrailSlicesPrevCount--;
|
||||
}
|
||||
|
||||
if (m_TrailSlicesCount == 0 && m_SmoothedTrailSlicesCount == 0) {
|
||||
m_GenerateSlices = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the mesh from the catmull rom verticies.
|
||||
/// </summary>
|
||||
private void BuildMesh()
|
||||
{
|
||||
m_Mesh.Clear();
|
||||
|
||||
if (m_TrailSlicesCount < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
// A fixed size array is used to store the vertex values. The starting index may not be at the beginning of the array.
|
||||
var startIndex = m_SmoothedTrailSlicesIndex - m_SmoothedTrailSlicesCount + 1;
|
||||
if (startIndex < 0) {
|
||||
startIndex = m_SmoothedTrailSlices.Length + startIndex;
|
||||
}
|
||||
|
||||
m_Vertices.Clear();
|
||||
m_UVs.Clear();
|
||||
m_Colors.Clear();
|
||||
m_Triangles.Clear();
|
||||
|
||||
for (int i = 0; i < m_SmoothedTrailSlicesCount; ++i) {
|
||||
var trailSlice = m_SmoothedTrailSlices[(startIndex + i) % m_SmoothedTrailSlices.Length];
|
||||
// The vertex position is the local position of the slice point. This will allow the trail to stay in the same position while the melee object is moving.
|
||||
m_Vertices.Add(m_Transform.InverseTransformPoint(trailSlice.Point));
|
||||
m_Vertices.Add(m_Transform.InverseTransformPoint(trailSlice.Point + trailSlice.Up * m_Length));
|
||||
// Set the UV value so a texture can be applied to the material.
|
||||
var u = Mathf.Max(i / (float)(m_SmoothedTrailSlicesCount - 1), 0.01f);
|
||||
m_UVs.Add(new Vector2(u, 0));
|
||||
m_UVs.Add(new Vector2(u, 1));
|
||||
// Optionally lerp between the start and end color.
|
||||
m_Colors.Add(Color.Lerp(m_EndColor, m_StartColor, u));
|
||||
// A clear color will fade the trail at the bottom.
|
||||
m_Colors.Add(Color.clear);
|
||||
|
||||
// Map the triangle indices to the vertex element.
|
||||
if (i < m_SmoothedTrailSlicesCount - 1) {
|
||||
// First triangle.
|
||||
m_Triangles.Add((i * 2));
|
||||
m_Triangles.Add((i * 2) + 1);
|
||||
m_Triangles.Add((i * 2) + 2);
|
||||
|
||||
// Second triangle.
|
||||
m_Triangles.Add((i * 2) + 2);
|
||||
m_Triangles.Add((i * 2) + 1);
|
||||
m_Triangles.Add((i * 2) + 3);
|
||||
}
|
||||
}
|
||||
|
||||
// Assign the values so the mesh will be displayed on the screen. The list version is used to prevent allocations when the mesh changes size.
|
||||
m_Mesh.SetVertices(m_Vertices);
|
||||
m_Mesh.SetUVs(0, m_UVs);
|
||||
m_Mesh.SetColors(m_Colors);
|
||||
m_Mesh.SetTriangles(m_Triangles, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops generating the trail.
|
||||
/// </summary>
|
||||
public void StopGeneration()
|
||||
{
|
||||
m_Transform.parent = null;
|
||||
m_GenerateSlices = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f4224c12740b644f82a0f901a35061e
|
||||
timeCreated: 1531917952
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 370
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user