/** * Utility method to carry out tasks required for detonation events. These are *received* detonations - that is, * they have come into Unity from an external source, so we need to make sure any internal entities (i.e., entities * "puppeted" by Unity) are affected appropriately (i.e., damage, appearance etc). * * @param detonations the data for the detonation events */ private void HandleDetonations( DetonateMunitionData[] detonations ) { foreach( DetonateMunitionData detonateMunitionData in detonations ) { // Log detonation events if necessary... if( showLogging ) { LVCPair<LVCGame.EntityData, GameObject> entityDataAndGameObject = this.lvcUnityAmbassador.GameObjectAndEntityDataForLvcId( detonateMunitionData.targeting.firingId ); if( entityDataAndGameObject != null ) { EntityData entityData = entityDataAndGameObject.A; Debug.Log( entityData.id.lvcType+"["+entityData.id.marking+"] detonated "+LVCUtils.DisplayFormatted(detonateMunitionData) ); } else { Debug.Log( "Indirect fire of "+detonateMunitionData.descriptor.quantity+" rounds of "+detonateMunitionData.targeting.munitionType+"." ); } } // handle the detonation event and affect entities as needed LVCGame.Vector3 lvcPosition = LVCUtils.llaToLtp( detonateMunitionData.targeting.position ); UnityEngine.Vector3 unityPosition = LVCUtils.LVCGameCoords_to_UnityCoords( lvcPosition ); string munitionTypeName = detonateMunitionData.targeting.munitionType; GameObject detonationPrefab = null; if( munitionDetonationMap.TryGetValue( munitionTypeName, out detonationPrefab ) ) { GameObject prefab = Instantiate( detonationPrefab, unityPosition, Quaternion.identity ) as GameObject; // make this the parent of the new prefab - keeps things organised, so we don't get prfeabs popping // up in the "root" tree prefab.transform.parent = gameObject.transform; // Note that an actual application may wish to ensure that ground based detonation prefabs are ground // clamped, but that aerial weapons are not. // Work out which entities have been hit by the explosion // Note that the damage effect level and effective radius is hard coded. An actual application // would probably need to make this dependent on the munition (and possibly the target // vulerability to munition). Here we use a very simplistic damage model. float maxMunitionDamageEffect = 0.5F; float maxEffectRadius = 10.0f; LVCPair<BasicLVCEntity, float>[] affectedEntities = lvcUnityAmbassador.GetAffectedEntities( unityPosition, maxEffectRadius ); foreach( LVCPair<BasicLVCEntity, float> affectedEntity in affectedEntities ) { BasicLVCEntity basicLvcEntity = affectedEntity.A; // entity affected by detonation float distance = affectedEntity.B; // distance of affected entity from from detonation // decrease damage based on inverse square law of distance of target from detonation location float actualDamageEffect = LVCUtils.SquareDecay( maxMunitionDamageEffect, maxEffectRadius, distance ); EntityDataManager entityDataManager = basicLvcEntity.GetEntityDataManager(); float damage = LVCUtils.ConstrainValue( entityDataManager.GetDamage()+actualDamageEffect, 0.0F, 1.0F ); entityDataManager.SetDamage( damage ); } } else { if( smokeMunitionPrefab != null ) { string[] nameAndColor = munitionTypeName.Split ('-'); if( nameAndColor.Length==2 ) { Color smokeColor = Color.black; if( smokeMunitionColorMap.TryGetValue(nameAndColor[0], out smokeColor) ) { GameObject prefab = Instantiate( smokeMunitionPrefab, unityPosition, Quaternion.identity ) as GameObject; // make this the parent of the new prefab - keeps things organised. prefab.transform.parent = gameObject.transform; // set the smoke color Renderer[] renderers = prefab.GetComponentsInChildren<Renderer>(); foreach( Renderer renderer in renderers ) foreach( Material material in renderer.materials ) material.color = smokeColor; // make sure the flare is on the ground, but don't change orientation DoGroundClamping( prefab, false ); } } } } } if(showLogging && detonations.Length>0) Debug.Log(detonations.Length + " External Detonation Events Handled."); }
/** * Fires a detonate munition event. This is triggered as a result of an *incoming* LVC update * event triggered by an LVC Game external to this one, meaning that the equivalent Unity game * object should be detonate a munition. * * @param data data associated with the event * @return true if the event was handled successfully */ public bool DetonateMunition( ref DetonateMunitionData data ) { lock( pendingExternalDetonationLock ) { // Debug.Log("External DETONATEMUNITION event received."); // add the data as a pending external deletion. Since this event arrived "outside" // Unity's event/threading system, this will eventually be handled by the LVCHelper // Monobehaviour during an Update() event. pendingExternalDetonations.Add( data ); } return true; }