diff --git a/Assets/Prefabs/Missiles/ArrowMissile.prefab b/Assets/Prefabs/Missiles/ArrowMissile.prefab index a51b28ad9b..494e59711e 100644 --- a/Assets/Prefabs/Missiles/ArrowMissile.prefab +++ b/Assets/Prefabs/Missiles/ArrowMissile.prefab @@ -150,19 +150,6 @@ MonoBehaviour: PreviewIndex: 0 PreviewID: 3 PreviewClip: 0 ---- !u!135 &135236093773449130 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1712884651827938} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 0 - serializedVersion: 2 - m_Radius: 0.4 - m_Center: {x: 0, y: 0, z: 0} --- !u!108 &108732554255048532 Light: m_ObjectHideFlags: 0 @@ -250,33 +237,3 @@ MonoBehaviour: PostImpactLifespanInSeconds: 0.6 PostImpactLightMultiplier: 1.5 ImpactSound: 4 ---- !u!54 &54102960107042576 -Rigidbody: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1712884651827938} - serializedVersion: 2 - m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 - m_UseGravity: 0 - m_IsKinematic: 1 - m_Interpolate: 0 - m_Constraints: 0 - m_CollisionDetection: 0 ---- !u!64 &64298782196861766 -MeshCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1712884651827938} - m_Material: {fileID: 0} - m_IsTrigger: 1 - m_Enabled: 0 - serializedVersion: 4 - m_Convex: 1 - m_CookingOptions: 30 - m_Mesh: {fileID: 0} diff --git a/Assets/Prefabs/Missiles/ColdMissile.prefab b/Assets/Prefabs/Missiles/ColdMissile.prefab index 8799a3630d..f6309cad5c 100644 --- a/Assets/Prefabs/Missiles/ColdMissile.prefab +++ b/Assets/Prefabs/Missiles/ColdMissile.prefab @@ -149,19 +149,6 @@ MonoBehaviour: PreviewIndex: 0 PreviewID: 3 PreviewClip: 0 ---- !u!135 &135961771109985534 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.4 - m_Center: {x: 0, y: 0, z: 0} --- !u!108 &108958489047367644 Light: m_ObjectHideFlags: 0 @@ -248,20 +235,4 @@ MonoBehaviour: LifespanInSeconds: 8 PostImpactLifespanInSeconds: 0.6 PostImpactLightMultiplier: 1.5 - ImpactSound: 90 ---- !u!54 &54482902062701562 -Rigidbody: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - serializedVersion: 2 - m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 - m_UseGravity: 0 - m_IsKinematic: 0 - m_Interpolate: 0 - m_Constraints: 0 - m_CollisionDetection: 0 + ImpactSound: 90 \ No newline at end of file diff --git a/Assets/Prefabs/Missiles/FireMissile.prefab b/Assets/Prefabs/Missiles/FireMissile.prefab index 4792974a82..c093004182 100644 --- a/Assets/Prefabs/Missiles/FireMissile.prefab +++ b/Assets/Prefabs/Missiles/FireMissile.prefab @@ -149,19 +149,6 @@ MonoBehaviour: PreviewIndex: 0 PreviewID: 3 PreviewClip: 0 ---- !u!135 &135961771109985534 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.4 - m_Center: {x: 0, y: 0, z: 0} --- !u!108 &108958489047367644 Light: m_ObjectHideFlags: 0 @@ -248,20 +235,4 @@ MonoBehaviour: LifespanInSeconds: 8 PostImpactLifespanInSeconds: 0.6 PostImpactLightMultiplier: 1.5 - ImpactSound: 89 ---- !u!54 &54482902062701562 -Rigidbody: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - serializedVersion: 2 - m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 - m_UseGravity: 0 - m_IsKinematic: 0 - m_Interpolate: 0 - m_Constraints: 0 - m_CollisionDetection: 0 + ImpactSound: 89 \ No newline at end of file diff --git a/Assets/Prefabs/Missiles/MagicMissile.prefab b/Assets/Prefabs/Missiles/MagicMissile.prefab index 801c2d8225..1358b288ef 100644 --- a/Assets/Prefabs/Missiles/MagicMissile.prefab +++ b/Assets/Prefabs/Missiles/MagicMissile.prefab @@ -149,19 +149,6 @@ MonoBehaviour: PreviewIndex: 0 PreviewID: 3 PreviewClip: 0 ---- !u!135 &135961771109985534 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.4 - m_Center: {x: 0, y: 0, z: 0} --- !u!108 &108958489047367644 Light: m_ObjectHideFlags: 0 @@ -248,20 +235,4 @@ MonoBehaviour: LifespanInSeconds: 8 PostImpactLifespanInSeconds: 0.6 PostImpactLightMultiplier: 1.5 - ImpactSound: 86 ---- !u!54 &54482902062701562 -Rigidbody: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - serializedVersion: 2 - m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 - m_UseGravity: 0 - m_IsKinematic: 0 - m_Interpolate: 0 - m_Constraints: 0 - m_CollisionDetection: 0 + ImpactSound: 86 \ No newline at end of file diff --git a/Assets/Prefabs/Missiles/PoisonMissile.prefab b/Assets/Prefabs/Missiles/PoisonMissile.prefab index c3d9e374d7..7e91357e8b 100644 --- a/Assets/Prefabs/Missiles/PoisonMissile.prefab +++ b/Assets/Prefabs/Missiles/PoisonMissile.prefab @@ -149,19 +149,6 @@ MonoBehaviour: PreviewIndex: 0 PreviewID: 3 PreviewClip: 0 ---- !u!135 &135961771109985534 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.4 - m_Center: {x: 0, y: 0, z: 0} --- !u!108 &108958489047367644 Light: m_ObjectHideFlags: 0 @@ -248,20 +235,4 @@ MonoBehaviour: LifespanInSeconds: 8 PostImpactLifespanInSeconds: 0.6 PostImpactLightMultiplier: 1.5 - ImpactSound: 87 ---- !u!54 &54482902062701562 -Rigidbody: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - serializedVersion: 2 - m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 - m_UseGravity: 0 - m_IsKinematic: 0 - m_Interpolate: 0 - m_Constraints: 0 - m_CollisionDetection: 0 + ImpactSound: 87 \ No newline at end of file diff --git a/Assets/Prefabs/Missiles/ShockMissile.prefab b/Assets/Prefabs/Missiles/ShockMissile.prefab index ac61e7d00a..595a0e03cd 100644 --- a/Assets/Prefabs/Missiles/ShockMissile.prefab +++ b/Assets/Prefabs/Missiles/ShockMissile.prefab @@ -149,19 +149,6 @@ MonoBehaviour: PreviewIndex: 0 PreviewID: 3 PreviewClip: 0 ---- !u!135 &135961771109985534 -SphereCollider: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - m_Material: {fileID: 0} - m_IsTrigger: 0 - m_Enabled: 1 - serializedVersion: 2 - m_Radius: 0.4 - m_Center: {x: 0, y: 0, z: 0} --- !u!108 &108958489047367644 Light: m_ObjectHideFlags: 0 @@ -248,20 +235,4 @@ MonoBehaviour: LifespanInSeconds: 8 PostImpactLifespanInSeconds: 0.6 PostImpactLightMultiplier: 1.5 - ImpactSound: 88 ---- !u!54 &54482902062701562 -Rigidbody: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1770169996000996} - serializedVersion: 2 - m_Mass: 1 - m_Drag: 0 - m_AngularDrag: 0.05 - m_UseGravity: 0 - m_IsKinematic: 0 - m_Interpolate: 0 - m_Constraints: 0 - m_CollisionDetection: 0 + ImpactSound: 88 \ No newline at end of file diff --git a/Assets/Scripts/Game/DaggerfallMissile.cs b/Assets/Scripts/Game/DaggerfallMissile.cs index 2df211f07e..44598894e5 100644 --- a/Assets/Scripts/Game/DaggerfallMissile.cs +++ b/Assets/Scripts/Game/DaggerfallMissile.cs @@ -4,7 +4,7 @@ // License: MIT License (http://www.opensource.org/licenses/mit-license.php) // Source Code: https://github.com/Interkarma/daggerfall-unity // Original Author: Gavin Clayton (interkarma@dfworkshop.net) -// Contributors: Allofich +// Contributors: Allofich, Numidium // // Notes: // @@ -27,9 +27,6 @@ namespace DaggerfallWorkshop.Game /// Currently ranged missiles can only move in a straight line as per classic. /// [RequireComponent(typeof(Light))] - [RequireComponent(typeof(SphereCollider))] - [RequireComponent(typeof(MeshCollider))] - [RequireComponent(typeof(Rigidbody))] [RequireComponent(typeof(DaggerfallAudioSource))] public class DaggerfallMissile : MonoBehaviour { @@ -64,11 +61,10 @@ public class DaggerfallMissile : MonoBehaviour public const float SphereCastRadius = 0.25f; public const float TouchRange = 3.0f; + Vector3 colliderPosition; Vector3 direction; Light myLight; - SphereCollider myCollider; DaggerfallAudioSource audioSource; - Rigidbody myRigidbody; Billboard myBillboard; bool forceDisableSpellLighting; bool noSpellsSpatialBlend = false; @@ -87,6 +83,7 @@ public class DaggerfallMissile : MonoBehaviour bool isArrowSummoned = false; GameObject goModel = null; EnemySenses enemySenses; + int layerMask; List targetEntities = new List(); @@ -182,14 +179,6 @@ private void Start() initialRange = myLight.range; initialIntensity = myLight.intensity; - // Setup collider - myCollider = GetComponent(); - myCollider.radius = ColliderRadius; - - // Setup rigidbody - myRigidbody = GetComponent(); - myRigidbody.useGravity = false; - // Use payload when available if (payload != null) { @@ -216,11 +205,7 @@ private void Start() if (isArrow) { // Create and orient 3d arrow - goModel = GameObjectHelper.CreateDaggerfallMeshGameObject(99800, transform); - MeshCollider arrowCollider = goModel.GetComponent(); - arrowCollider.sharedMesh = goModel.GetComponent().sharedMesh; - arrowCollider.convex = true; - arrowCollider.isTrigger = true; + goModel = GameObjectHelper.CreateDaggerfallMeshGameObject(99800, transform, ignoreCollider: true); // Offset up so it comes from same place LOS check is done from Vector3 adjust; @@ -234,8 +219,6 @@ private void Start() { // Adjust slightly downward to match bow animation adjust = (GameManager.Instance.MainCamera.transform.rotation * -Caster.transform.up) * 0.11f; - // Offset forward to avoid collision with player - adjust += GameManager.Instance.MainCamera.transform.forward * 0.6f; // Adjust to the right or left to match bow animation if (!GameManager.Instance.WeaponManager.ScreenWeapon.FlipHorizontal) adjust += GameManager.Instance.MainCamera.transform.right * 0.15f; @@ -248,9 +231,12 @@ private void Start() goModel.layer = gameObject.layer; } - // Ignore missile collision with caster (this is a different check to AOE targets) - if (caster) - Physics.IgnoreCollision(caster.GetComponent(), this.GetComponent()); + string layerName; + if (caster && caster != GameManager.Instance.PlayerEntityBehaviour) + layerName = "SpellMissiles"; + else + layerName = "Player"; + layerMask = ~(1 << LayerMask.NameToLayer(layerName)); } private void Update() @@ -281,14 +267,14 @@ private void Update() { // Transform missile along direction vector transform.position += (direction * MovementSpeed) * Time.deltaTime; - // Update lifespan and self-destruct if expired (e.g. spell fired straight up and will never hit anything) - lifespan += Time.deltaTime; if (lifespan > LifespanInSeconds) Destroy(gameObject); } else { + // Transform missile to point of collision. + transform.position = colliderPosition; // Notify listeners work is done and automatically assign impact if (!impactAssigned) { @@ -313,19 +299,35 @@ private void Update() UpdateLight(); } - #endregion - - #region Collision Handling - - private void OnCollisionEnter(Collision collision) + private void FixedUpdate() { - DoCollision(collision, null); + if (!missileReleased || impactDetected) + return; + lifespan += Time.fixedDeltaTime; + // Do fixed-interval transformation with raycast lookahead. + var displacement = (direction * MovementSpeed) * Time.fixedDeltaTime; + RaycastHit hitInfo; + bool castFoundHit; + if (isArrow || lifespan == Time.fixedDeltaTime) // First test should always be a raycast in case the caster is hugging a wall. + castFoundHit = Physics.Raycast(colliderPosition, direction, out hitInfo, displacement.magnitude + ColliderRadius, layerMask); + else + castFoundHit = Physics.SphereCast(colliderPosition, ColliderRadius, direction, out hitInfo, displacement.magnitude + ColliderRadius, layerMask); + if (castFoundHit) + { + // Place self at meeting point with collider and do collision logic. + if (isArrow) + colliderPosition = hitInfo.point - transform.forward * ColliderRadius; + else + colliderPosition += direction.normalized * hitInfo.distance; // Stop at center of sphere cast. + DoCollision(null, hitInfo.collider); + } + else + colliderPosition += displacement; } - private void OnTriggerEnter(Collider other) - { - DoCollision(null, other); - } + #endregion + + #region Collision Handling void DoCollision(Collision collision, Collider other) { @@ -333,16 +335,6 @@ void DoCollision(Collision collision, Collider other) if (impactDetected) return; - // Set my collider to trigger and rigidbody to kinematic immediately after impact - // This helps prevent mobiles from walking over low missiles or the missile bouncing off in some other direction - // Seems to eliminate the combined worst-case scenario where mobile will "ride" a missile bounce, throwing them high into the air - // Now the worst that seems to happen is mobile will "bump" over low missiles occasionally - // TODO: Review later and find a better way to eliminate issue other than this quick workaround - if (myCollider) - myCollider.isTrigger = true; - if (myRigidbody) - myRigidbody.isKinematic = true; - // Play spell impact animation, this replaces spell missile animation if (elementType != ElementTypes.None && targetType != TargetTypes.ByTouch) { @@ -380,7 +372,7 @@ void DoCollision(Collision collision, Collider other) // If missile is area at range if (targetType == TargetTypes.AreaAtRange) { - DoAreaOfEffect(transform.position); + DoAreaOfEffect(colliderPosition); } } @@ -410,11 +402,6 @@ void DoTouch() { transform.position = caster.transform.position; - // Touch does not use default missile collider - // This prevent touch missile check colliding with self and blocking spell transfer - if (myCollider) - myCollider.enabled = false; - DaggerfallEntityBehaviour entityBehaviour = GetEntityTargetInTouchRange(GetAimPosition(), GetAimDirection()); if (entityBehaviour && entityBehaviour != caster) { @@ -431,7 +418,8 @@ void DoTouch() void DoMissile() { direction = GetAimDirection(); - transform.position = GetAimPosition() + direction * ArmLength; + transform.position = GetAimPosition(); + colliderPosition = transform.position; missileReleased = true; } @@ -440,7 +428,7 @@ void DoAreaOfEffect(Vector3 position, bool ignoreCaster = false) { List entities = new List(); - transform.position = position; + colliderPosition = position; // Collect AOE targets and ignore duplicates Collider[] overlaps = Physics.OverlapSphere(position, ExplosionRadius);