8 using System.Collections;
10 namespace Valve.VR.InteractionSystem
13 public class Arrow : MonoBehaviour
15 public ParticleSystem glintParticle;
16 public Rigidbody arrowHeadRB;
17 public Rigidbody shaftRB;
19 public PhysicMaterial targetPhysMaterial;
21 private Vector3 prevPosition;
22 private Quaternion prevRotation;
23 private Vector3 prevVelocity;
24 private Vector3 prevHeadPosition;
32 private bool inFlight;
33 private bool released;
34 private bool hasSpreadFire =
false;
36 private int travelledFrames = 0;
38 private GameObject scaleParentObject = null;
44 Physics.IgnoreCollision( shaftRB.GetComponent<Collider>(),
Player.instance.headCollider );
51 if ( released && inFlight )
53 prevPosition = transform.position;
54 prevRotation = transform.rotation;
55 prevVelocity = GetComponent<Rigidbody>().velocity;
56 prevHeadPosition = arrowHeadRB.transform.position;
63 public void ArrowReleased(
float inputVelocity )
68 airReleaseSound.Play();
70 if ( glintParticle != null )
75 if ( gameObject.GetComponentInChildren<
FireSource>().isBurning )
77 fireReleaseSound.Play();
81 RaycastHit[] hits = Physics.SphereCastAll( transform.position, 0.01f, transform.forward, 0.80f, Physics.DefaultRaycastLayers, QueryTriggerInteraction.Ignore );
82 foreach ( RaycastHit hit
in hits )
84 if ( hit.collider.gameObject != gameObject && hit.collider.gameObject != arrowHeadRB.gameObject && hit.collider !=
Player.instance.headCollider )
86 Destroy( gameObject );
92 prevPosition = transform.position;
93 prevRotation = transform.rotation;
94 prevHeadPosition = arrowHeadRB.transform.position;
95 prevVelocity = GetComponent<Rigidbody>().velocity;
97 Destroy( gameObject, 30 );
102 void OnCollisionEnter( Collision collision )
106 Rigidbody rb = GetComponent<Rigidbody>();
107 float rbSpeed = rb.velocity.sqrMagnitude;
108 bool canStick = ( targetPhysMaterial != null && collision.collider.sharedMaterial == targetPhysMaterial && rbSpeed > 0.2f );
109 bool hitBalloon = collision.collider.gameObject.GetComponent<
Balloon>() != null;
111 if ( travelledFrames < 2 && !canStick )
114 transform.position = prevPosition - prevVelocity * Time.deltaTime;
115 transform.rotation = prevRotation;
117 Vector3 reflfectDir = Vector3.Reflect( arrowHeadRB.velocity, collision.contacts[0].normal );
118 arrowHeadRB.velocity = reflfectDir * 0.25f;
119 shaftRB.velocity = reflfectDir * 0.25f;
125 if ( glintParticle != null )
127 glintParticle.Stop( true );
131 if ( rbSpeed > 0.1f )
133 hitGroundSound.Play();
139 if ( arrowFire != null && arrowFire.isBurning && ( fireSourceOnTarget != null ) )
141 if ( !hasSpreadFire )
143 collision.collider.gameObject.SendMessageUpwards(
"FireExposure", gameObject, SendMessageOptions.DontRequireReceiver );
144 hasSpreadFire =
true;
151 if ( rbSpeed > 0.1f || hitBalloon )
153 collision.collider.gameObject.SendMessageUpwards(
"ApplyDamage", SendMessageOptions.DontRequireReceiver );
154 gameObject.SendMessage(
"HasAppliedDamage", SendMessageOptions.DontRequireReceiver );
161 transform.position = prevPosition;
162 transform.rotation = prevRotation;
163 arrowHeadRB.velocity = prevVelocity;
164 Physics.IgnoreCollision( arrowHeadRB.GetComponent<Collider>(), collision.collider );
165 Physics.IgnoreCollision( shaftRB.GetComponent<Collider>(), collision.collider );
170 StickInTarget( collision, travelledFrames < 2 );
174 if (
Player.instance && collision.collider ==
Player.instance.headCollider )
176 Player.instance.PlayerShotSelf();
183 private void StickInTarget( Collision collision,
bool bSkipRayCast )
185 Vector3 prevForward = prevRotation * Vector3.forward;
190 RaycastHit[] hitInfo;
191 hitInfo = Physics.RaycastAll( prevHeadPosition - prevVelocity * Time.deltaTime, prevForward, prevVelocity.magnitude * Time.deltaTime * 2.0f );
192 bool properHit =
false;
193 for (
int i = 0; i < hitInfo.Length; ++i )
195 RaycastHit hit = hitInfo[i];
197 if ( hit.collider == collision.collider )
210 Destroy( glintParticle );
214 shaftRB.velocity = Vector3.zero;
215 shaftRB.angularVelocity = Vector3.zero;
216 shaftRB.isKinematic =
true;
217 shaftRB.useGravity =
false;
218 shaftRB.transform.GetComponent<BoxCollider>().enabled =
false;
220 arrowHeadRB.velocity = Vector3.zero;
221 arrowHeadRB.angularVelocity = Vector3.zero;
222 arrowHeadRB.isKinematic =
true;
223 arrowHeadRB.useGravity =
false;
224 arrowHeadRB.transform.GetComponent<BoxCollider>().enabled =
false;
226 hitTargetSound.Play();
231 scaleParentObject =
new GameObject(
"Arrow Scale Parent" );
232 Transform parentTransform = collision.collider.transform;
238 if ( parentTransform.parent )
240 parentTransform = parentTransform.parent;
244 scaleParentObject.transform.parent = parentTransform;
247 transform.parent = scaleParentObject.transform;
248 transform.rotation = prevRotation;
249 transform.position = prevPosition;
250 transform.position = collision.contacts[0].point - transform.forward * ( 0.75f - ( Util.RemapNumberClamped( prevVelocity.magnitude, 0f, 10f, 0.0f, 0.1f ) + Random.Range( 0.0f, 0.05f ) ) );
257 if ( scaleParentObject != null )
259 Destroy( scaleParentObject );