Exemplo n.º 1
0
    /// <summary>
    ///
    /// </summary>
    void Start()
    {
        // verify collider
        m_Collider = transform.GetComponent <Collider>();
        if (m_Collider == null)
        {
            Debug.LogError("Error (" + this + ") This component requires a collider. Disabling self!");
            this.enabled = false;
            return;
        }

        // find target damage handler
        if (TargetObject != null)
        {
            m_TargetDamageHandler = TargetObject.GetComponentInChildren <vp_DamageHandler>();
        }
        else
        {
            m_TargetDamageHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_Collider);
            if (m_TargetDamageHandler != null)
            {
                TargetObject = m_TargetDamageHandler.gameObject;
            }
        }
    }
Exemplo n.º 2
0
	/// <summary>
	/// 
	/// </summary>
	void OnTriggerEnter(Collider col)
	{

		// return if this is not a relevant object. TIP: this check can be expanded
		if (col.gameObject.layer == vp_Layer.Debris
			|| col.gameObject.layer == vp_Layer.Pickup)
			return;

		// try to find a damagehandler on the target and abort on fail
		m_TargetDamageHandler = vp_DamageHandler.GetDamageHandlerOfCollider(col);
		if (m_TargetDamageHandler == null)
			return;

		// abort if target is already dead
		// NOTE: this deals with cases of multiple 'OnTriggerEnter' calls on contact
		if (m_TargetDamageHandler.CurrentHealth <= 0)
			return;

		// try to find a respawner on the target to see if it's currently OK to kill it
		m_TargetRespawner = vp_Respawner.GetByCollider(col);
		if (m_TargetRespawner != null)
		{
			// abort if target has respawned within one second before this call.
			// NOTE: this addresses a case where 'OnTriggerEnter' is called when
			// teleporting (respawning) away from the trigger, resulting in the
			// object getting insta-killed on respawn. it will only work if the
			// target gameobject has a vp_Respawner-derived component
			if (Time.time < m_TargetRespawner.LastRespawnTime + 1.0f)
				return;
		}

		m_TargetDamageHandler.Damage(new vp_DamageInfo(m_TargetDamageHandler.CurrentHealth, m_TargetDamageHandler.Transform, vp_DamageInfo.DamageType.KillZone));

	}
    /// <summary>
    /// attempts to do damage using a regular Unity-message, and / or more advanced
    /// UFPS format damage (whichever is supported by the bullet and target)
    /// </summary>
    protected virtual void TryDamage()
    {
        // send primitive damage as UnityMessage. this allows support for many third party
        // systems (simply use a 'void Damage(float)' method in target MonoBehaviours)
        if ((DamageMode == vp_DamageInfo.DamageMode.UnityMessage) ||
            (DamageMode == vp_DamageInfo.DamageMode.Both))
        {
            m_Hit.collider.SendMessage(DamageMethodName, Damage, SendMessageOptions.DontRequireReceiver);
#if UNITY_EDITOR
            if (!m_DidWarnAboutBothMethodName &&
                (DamageMethodName == "Damage") &&
                (vp_DamageHandler.GetDamageHandlerOfCollider(m_Hit.collider) != null))
            {
                Debug.LogWarning("Warning (" + this + ") Target object has a vp_DamageHandler. When damaging it with DamageMode: 'UnityMessage' or 'Both', you probably want to change 'DamageMethodName' to something other than 'Damage', or too much damage might be applied.");
                m_DidWarnAboutBothMethodName = true;
            }
#endif
        }

        // send damage in UFPS format. this allows different damage types, and tracking damage source
        if ((DamageMode == vp_DamageInfo.DamageMode.DamageHandler) ||
            (DamageMode == vp_DamageInfo.DamageMode.Both))
        {
            m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_Hit.collider);
            if (m_TargetDHandler != null)
            {
                DoUFPSDamage();
            }
        }
    }
Exemplo n.º 4
0
    // Update is called once per frame
    void Update()
    {
        timer += Time.deltaTime;
        vp_DamageHandler vp_DamageHandler = simplePlayer.GetComponent <vp_DamageHandler>();

        score           = vp_DamageHandler.deathCount;
        scoreLabel.text = score.ToString();
        timeLabel.text  = timer.ToString();
    }
Exemplo n.º 5
0
    public void OnTriggerStay(Collider other)
    {
        vp_DamageHandler handler = other.GetComponent <vp_DamageHandler>();

        if (handler)
        {
            handler.Damage(new vp_DamageInfo(DamagePerSecond * Time.deltaTime, transform));
        }
    }
Exemplo n.º 6
0
        public override void OnAwake()
        {
            damageHandler = GetDefaultGameObject(targetGameObject.Value).GetComponent <vp_DamageHandler>();
            if (damageHandler == null)
            {
                Debug.LogError("Error: Unable to find the vp_DamageHandler component on " + targetGameObject.Value);
                return;
            }

            prevHealth = damageHandler.CurrentHealth;
        }
Exemplo n.º 7
0
    /// <summary>
    /// retrieves, finds and caches target damagehandlers for more
    /// efficient fetching in the future
    /// </summary>
    public static vp_DamageHandler GetDamageHandlerOfCollider(Collider col)
    {
        // try to fetch a known damagehandler on this target
        if (!Instances.TryGetValue(col, out m_GetDamageHandlerOfColliderResult))
        {
            // no damagehandler on record: see if there is one
            m_GetDamageHandlerOfColliderResult = col.transform.root.GetComponentInChildren <vp_DamageHandler>();
            Instances.Add(col, m_GetDamageHandlerOfColliderResult);                     // add result to the dictionary (even if null)
        }

        return(m_GetDamageHandlerOfColliderResult);
    }
Exemplo n.º 8
0
    /// <summary>
    /// this method is called when any object is damaged locally in the
    /// master scene, transmitting its new health to all remote clients.
    /// it is typically initiated by vp_DamageHandler
    /// </summary>
    protected virtual void TransmitDamage(Transform targetTransform, Transform sourceTransform, float damage)
    {
        // NOTES:
        // 1) players (vp_PlayerDamageHandlers) will have health synced perfectly across
        //		all machines at all times
        // 2) health of plain vp_DamageHandlers (props) is only kept in perfect sync if
        //		'SyncPropHealth' is true. however, when their health reaches zero on the
        //		master and a 'TransmitKill' message occurs the prop in question will
        //		always die immediately on all machines
        // 3) 'sourceTransform' is not used here, but needed for overrides that deal
        //		with more complex gameplay (see example in 'vp_DMDamageCallbacks')
        // 4) 'damage' is assumed to have already been updated in the master scene
        //		damage handler. it is not used here, but overrides can do a lot more with
        //		it (see example in 'vp_DMDamageCallbacks').
        // 5) 'damage' can be both positive and negative. a negative number will add health

        if (!PhotonNetwork.isMasterClient)
        {
            return;
        }

        int viewID = vp_MPMaster.GetViewIDOfTransform(targetTransform);

        if (viewID == 0)
        {
            return;
        }

        vp_DamageHandler d = GetDamageHandlerOfViewID(viewID);

        if (d == null)
        {
            return;
        }

        // abort if target already died (no health to update)
        if (d.CurrentHealth <= 0.0f)
        {
            return;
        }

        // abort if this is a prop and we're not supposed to sync prop health
        if (!SyncPropHealth && !(d is vp_PlayerDamageHandler))
        {
            return;
        }

        photonView.RPC("ReceiveObjectHealth", PhotonTargets.Others, viewID, (float)d.CurrentHealth);            // NOTE: cast to float required for Anti-Cheat Toolkit support
    }
Exemplo n.º 9
0
 /// <summary>
 ///
 /// </summary>
 void DoDamage()
 {
     m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_TargetCollider);
     if (m_TargetDHandler != null)
     {
         // target has a known damagehandler -> send damage in UFPS format.
         // this works with targets that have a vp_DamageHandler (or derived) component
         m_TargetDHandler.Damage(new vp_DamageInfo((DistanceModifier * Damage), Source, OriginalSource, vp_DamageInfo.DamageType.Explosion));
     }
     else if (!RequireDamageHandler)
     {
         // target is known to have no damagehandler -> send damage the 'Unity way'.
         // this works with targets that have a custom script with the standard
         // method: "Damage(float damage)"
         m_TargetCollider.gameObject.BroadcastMessage(DamageMessageName, (DistanceModifier * Damage), SendMessageOptions.DontRequireReceiver);
     }
 }
Exemplo n.º 10
0
    protected virtual void ReceiveObjectHealth(int viewID, float health, PhotonMessageInfo info)
    {
        //vp_MPDebug.Log("GOT OBJECT HEALTH!");

        if ((info.sender != PhotonNetwork.masterClient) ||
            (info.sender.isLocal))
        {
            return;
        }

        vp_DamageHandler d = GetDamageHandlerOfViewID(viewID);

        if (d == null)
        {
            return;
        }

        d.CurrentHealth = health;
    }
Exemplo n.º 11
0
    public virtual void ReceiveObjectKill(int viewId, PhotonMessageInfo info)
    {
        if (info.sender != PhotonNetwork.masterClient)
        {
            return;
        }

        vp_DamageHandler d = GetDamageHandlerOfViewID(viewId);

        if ((d == null) || (d is vp_PlayerDamageHandler))
        {
            return;
        }

        // cache respawner before we deactivate the object, or 'GetRespawnerOfViewID'
        // won't be able to find the deactivated object later
        GetRespawnerOfViewID(viewId);

        d.Die();
    }
Exemplo n.º 12
0
    void Start()
    {
        playerObject = GameObject.FindGameObjectWithTag("Player");

        charAnim = gameObject.GetComponentInChildren <Animation>();
        charAnim.animation["run"].wrapMode = WrapMode.Loop;
        //charAnim.animation["run"].wrapMode = WrapMode.Loop;
        controller    = GetComponent <CharacterController>();
        damageHandler = GetComponent <vp_DamageHandler>();
        //heading = Random.Range(0, 360);
        transform.eulerAngles = new Vector3(0, Random.Range(0, 360), 0);

        nextPlayerTest = Time.time + testPlayerDelay;

        AIState = "Wander";
        charAnim.CrossFade("run");
        firing = false;

        //playAnimIdle();
    }
Exemplo n.º 13
0
    /// <summary>
    /// caches and returns the damagehandler of the given photonview id.
    /// damagehandlers are stored in a dictionary that resets on level load
    /// </summary>
    public static vp_DamageHandler GetDamageHandlerOfViewID(int id)
    {
        vp_DamageHandler d = null;

        if (!m_DamageHandlersByViewID.TryGetValue(id, out d))
        {
            PhotonView p = PhotonView.Find(id);
            if (p != null)
            {
                d = p.transform.GetComponent <vp_DamageHandler>();
                if (d != null)
                {
                    m_DamageHandlersByViewID.Add(id, d);
                }
                return(d);
            }
            // NOTE: we do not add null results, since photonviews come and go
        }

        return(d);
    }
Exemplo n.º 14
0
    void Start()
    {
        // hide frost and heat icon
        //tempHeatColor = heatIcon.color;
        //tempHeatColor.a = 0.0f;
        //heatIcon.color = tempHeatColor;

        damg = player.GetComponent <vp_FPPlayerDamageHandler>();

        //Debug.Log (damg.GetType());

        //hide frost icon on start
        tempFrostColor   = frostIcon.color;
        tempFrostColor.a = 0.0f;
        frostIcon.color  = tempFrostColor;

        tempHeatColor = heatIcon.color;


        currentFrostTemp = (int)THERMAL_LIMITS.MAX_TEMP;
    }
Exemplo n.º 15
0
    /// <summary>
    ///
    /// </summary>
    void OnTriggerEnter(Collider col)
    {
        // return if this is not a relevant object. TIP: this check can be expanded
        if (col.gameObject.layer == vp_Layer.Debris ||
            col.gameObject.layer == vp_Layer.Pickup)
        {
            return;
        }

        // try to find a damagehandler on the target and abort on fail
        m_TargetDamageHandler = vp_DamageHandler.GetDamageHandlerOfCollider(col);
        if (m_TargetDamageHandler == null)
        {
            return;
        }

        // abort if target is already dead
        // NOTE: this deals with cases of multiple 'OnTriggerEnter' calls on contact
        if (m_TargetDamageHandler.CurrentHealth <= 0)
        {
            return;
        }

        // try to find a respawner on the target to see if it's currently OK to kill it
        m_TargetRespawner = vp_Respawner.GetByCollider(col);
        if (m_TargetRespawner != null)
        {
            // abort if target has respawned within one second before this call.
            // NOTE: this addresses a case where 'OnTriggerEnter' is called when
            // teleporting (respawning) away from the trigger, resulting in the
            // object getting insta-killed on respawn. it will only work if the
            // target gameobject has a vp_Respawner-derived component
            if (Time.time < m_TargetRespawner.LastRespawnTime + 1.0f)
            {
                return;
            }
        }

        m_TargetDamageHandler.Damage(new vp_DamageInfo(m_TargetDamageHandler.CurrentHealth, m_TargetDamageHandler.Transform, vp_DamageInfo.DamageType.KillZone));
    }
    /// <summary>
    ///
    /// </summary>
    static void CreateRespawnerForDamageHandler(vp_DamageHandler damageHandler)
    {
        if (damageHandler.gameObject.GetComponent <vp_Respawner>() || damageHandler.gameObject.GetComponent <vp_PlayerRespawner>())
        {
            return;
        }

        vp_Respawner respawner = null;

        if (damageHandler is vp_FPPlayerDamageHandler)
        {
            respawner = damageHandler.gameObject.AddComponent <vp_PlayerRespawner>();
        }
        else
        {
            respawner = damageHandler.gameObject.AddComponent <vp_Respawner>();
        }

        if (respawner == null)
        {
            return;
        }

        if (damageHandler.MinRespawnTime != -99999.0f)
        {
            respawner.MinRespawnTime = damageHandler.MinRespawnTime;
        }
        if (damageHandler.MaxRespawnTime != -99999.0f)
        {
            respawner.MaxRespawnTime = damageHandler.MaxRespawnTime;
        }
        if (damageHandler.RespawnCheckRadius != -99999.0f)
        {
            respawner.ObstructionRadius = damageHandler.RespawnCheckRadius;
        }
        if (damageHandler.RespawnSound != null)
        {
            respawner.SpawnSound = damageHandler.RespawnSound;
        }
    }
    /// <summary>
    /// retrieves, finds and caches target damagehandlers for more
    /// efficient fetching in the future
    /// </summary>
    public static vp_DamageHandler GetDamageHandlerOfCollider(Collider col)
    {
        m_GetDamageHandlerOfColliderResult = null;

        // try to fetch a known damagehandler on this target,
        if (!Instances.TryGetValue(col, out m_GetDamageHandlerOfColliderResult))
        {
            // no damagehandler info on record for this collider: see if we can find
            // one on the transform or any of its ancestors (the lowest ancestor with
            // a damagehandler will be cached as belonging to this collider)
            Transform t = col.transform;
            while ((t != null) && (m_GetDamageHandlerOfColliderResult == null))
            {
                m_GetDamageHandlerOfColliderResult = t.GetComponent <vp_DamageHandler>();
                t = t.parent;
            }

            Instances.Add(col, m_GetDamageHandlerOfColliderResult);                     // add result to the dictionary (even if null)
        }

        return(m_GetDamageHandlerOfColliderResult);
    }
	/// <summary>
	/// 
	/// </summary>
	void Start()
	{
		
		// verify collider
		m_Collider = transform.GetComponent<Collider>();
		if (m_Collider == null)
		{
			Debug.LogError("Error (" + this + ") This component requires a collider. Disabling self!");
			this.enabled = false;
			return;
		}

		// find target damage handler
		if (TargetObject != null)
			m_TargetDamageHandler = TargetObject.GetComponentInChildren<vp_DamageHandler>();
		else
		{
			m_TargetDamageHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_Collider);
			if(m_TargetDamageHandler != null)
				TargetObject = m_TargetDamageHandler.gameObject;
		}

	}
Exemplo n.º 19
0
 public override void SetValue(object value) { mValue = (vp_DamageHandler)value; }
Exemplo n.º 20
0
 public override void SetValue(object value)
 {
     mValue = (vp_DamageHandler)value;
 }
Exemplo n.º 21
0
	/// <summary>
	/// 
	/// </summary>
	void DoDamage()
	{

		m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_TargetCollider);
		if (m_TargetDHandler != null)
		{
			// target has a known damagehandler -> send damage in UFPS format.
			// this works with targets that have a vp_DamageHandler (or derived) component
			m_TargetDHandler.Damage(new vp_DamageInfo((DistanceModifier * Damage), Source, OriginalSource, vp_DamageInfo.DamageType.Explosion));
		}
		else if (!RequireDamageHandler)
		{
			// target is known to have no damagehandler -> send damage the 'Unity way'.
			// this works with targets that have a custom script with the standard
			// method: "Damage(float damage)"
			m_TargetCollider.gameObject.BroadcastMessage(DamageMessageName, (DistanceModifier * Damage), SendMessageOptions.DontRequireReceiver);
		}

	}
Exemplo n.º 22
0
	/// <summary>
	/// 
	/// </summary>
	static void CreateRespawnerForDamageHandler(vp_DamageHandler damageHandler)
	{

		if (damageHandler.gameObject.GetComponent<vp_Respawner>() || damageHandler.gameObject.GetComponent<vp_PlayerRespawner>())
			return;

		vp_Respawner respawner = null;

		if(damageHandler is vp_FPPlayerDamageHandler)
			respawner = damageHandler.gameObject.AddComponent<vp_PlayerRespawner>();
		else
			respawner = damageHandler.gameObject.AddComponent<vp_Respawner>();

		if (respawner == null)
			return;

		if (damageHandler.MinRespawnTime != -99999.0f)
			respawner.MinRespawnTime = damageHandler.MinRespawnTime;
		if (damageHandler.MaxRespawnTime != -99999.0f)
			respawner.MaxRespawnTime = damageHandler.MaxRespawnTime;
		if (damageHandler.RespawnCheckRadius != -99999.0f)
			respawner.ObstructionRadius = damageHandler.RespawnCheckRadius;
		if (damageHandler.RespawnSound != null)
			respawner.SpawnSound = damageHandler.RespawnSound;

	}
Exemplo n.º 23
0
	/// <summary>
	/// retrieves, finds and caches target damagehandlers for more
	/// efficient fetching in the future
	/// </summary>
	public static vp_DamageHandler GetDamageHandlerOfCollider(Collider col)
	{

		// try to fetch a known damagehandler on this target
		if (!DamageHandlersByCollider.TryGetValue(col, out m_GetDamageHandlerOfColliderResult))
		{
			// no damagehandler on record: see if there is one
			m_GetDamageHandlerOfColliderResult = col.transform.root.GetComponentInChildren<vp_DamageHandler>();
			DamageHandlersByCollider.Add(col, m_GetDamageHandlerOfColliderResult);		// add result to the dictionary (even if null)
		}

		return m_GetDamageHandlerOfColliderResult;

	}
Exemplo n.º 24
0
	/// <summary>
	/// spawns effects, applies forces and damage to close by objects
	/// and flags the explosion for removal
	/// </summary>
	void DoExplode()
	{

		m_HaveExploded = true;

		// spawn effects gameobjects
		foreach (GameObject fx in FXPrefabs)
		{
			if (fx != null)
			{
#if UNITY_EDITOR
				Component[] c;
				c = fx.GetComponents<vp_Explosion>();	// OK from a performance perspective because it only occurs in editor
				if (c.Length > 0)
					Debug.LogError("Error: vp_Explosion->FXPrefab must not be a vp_Explosion (risk of infinite loop).");
				else
#endif
					vp_Utility.Instantiate(fx, Transform.position, Transform.rotation);
			}
		}

		// clear the list of affected objects in case this explosion has been pooled
		m_DHandlersHitByThisExplosion.Clear();

		// apply shockwave to all rigidbodies and FPSPlayers within range, but
		// ignore small and walk-thru objects such as debris, triggers and water
		Collider[] colliders = Physics.OverlapSphere(Transform.position, Radius, vp_Layer.Mask.IgnoreWalkThru);
		foreach (Collider hit in colliders)
		{

			if (hit.gameObject.isStatic)
				continue;

			m_DistanceModifier = 0.0f;

			if ((hit != null) && (hit != this.collider))
			{

				m_TargetCollider = hit;
				m_TargetTransform = hit.transform;

				// --- add camera shake ---
				AddUFPSCameraShake();

				// --- abort if we have no line of sight to target ---
				if (TargetInCover())
					continue;

				// --- try to add force ---
				m_TargetRigidbody = hit.rigidbody;
				if (m_TargetRigidbody != null)		// target has a rigidbody: apply force using Unity physics
					AddRigidbodyForce();
				else 								// target has no rigidbody. try and apply force using UFPS physics
					AddUFPSForce();

				// --- try to add damage ---
				m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_TargetCollider);
				if (m_TargetDHandler != null)		// this was a known damagehandler target: send the damage!
					DoUFPSDamage(DistanceModifier * Damage);
				else if (!RequireDamageHandler)		// this target was known to have no damagehandler. send damage using unitymessage (if allowed)
					DoUnityDamage(DistanceModifier * Damage);
							
				//Debug.Log(m_TargetTransform.name + Time.time);	// SNIPPET: to dump affected objects

			}

		}

		// play explosion sound
		Audio.clip = Sound;
		Audio.pitch = Random.Range(SoundMinPitch, SoundMaxPitch) * Time.timeScale;
		if (!Audio.playOnAwake)
			Audio.Play();

	}
Exemplo n.º 25
0
    /// <summary>
    /// spawns effects, applies forces and damage to close by objects
    /// and flags the explosion for removal
    /// </summary>
    void DoExplode()
    {
        m_HaveExploded = true;

        // spawn effects gameobjects
        foreach (GameObject fx in FXPrefabs)
        {
            if (fx != null)
            {
#if UNITY_EDITOR
                Component[] c;
                c = fx.GetComponents <vp_Explosion>();                  // OK from a performance perspective because it only occurs in editor
                if (c.Length > 0)
                {
                    Debug.LogError("Error: vp_Explosion->FXPrefab must not be a vp_Explosion (risk of infinite loop).");
                }
                else
#endif
                vp_Utility.Instantiate(fx, Transform.position, Transform.rotation);
            }
        }

        // clear the list of affected objects in case this explosion has been pooled
        m_DHandlersHitByThisExplosion.Clear();

        // apply shockwave to all rigidbodies and FPSPlayers within range, but
        // ignore small and walk-thru objects such as debris, triggers and water
        Collider[] colliders = Physics.OverlapSphere(Transform.position, Radius, vp_Layer.Mask.IgnoreWalkThru);
        foreach (Collider hit in colliders)
        {
            if (hit.gameObject.isStatic)
            {
                continue;
            }

            m_DistanceModifier = 0.0f;

            if ((hit != null) && (hit != this.GetComponent <Collider>()))
            {
                m_TargetCollider  = hit;
                m_TargetTransform = hit.transform;

                // --- add camera shake ---
                AddUFPSCameraShake();

                // --- abort if we have no line of sight to target ---
                if (TargetInCover())
                {
                    continue;
                }

                // --- try to add force ---
                m_TargetRigidbody = hit.GetComponent <Rigidbody>();
                if (m_TargetRigidbody != null)                          // target has a rigidbody: apply force using Unity physics
                {
                    AddRigidbodyForce();
                }
                else                                                                            // target has no rigidbody. try and apply force using UFPS physics
                {
                    AddUFPSForce();
                }

                // --- try to add damage ---
                m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_TargetCollider);
                if (m_TargetDHandler != null)                           // this was a known damagehandler target: send the damage!
                {
                    DoUFPSDamage(DistanceModifier * Damage);
                }
                else if (!RequireDamageHandler)                         // this target was known to have no damagehandler. send damage using unitymessage (if allowed)
                {
                    DoUnityDamage(DistanceModifier * Damage);
                }

                //Debug.Log(m_TargetTransform.name + Time.time);	// SNIPPET: to dump affected objects
            }
        }

        // play explosion sound
        Audio.clip  = Sound;
        Audio.pitch = Random.Range(SoundMinPitch, SoundMaxPitch) * Time.timeScale;
        if (!Audio.playOnAwake)
        {
            Audio.Play();
        }
    }
Exemplo n.º 26
0
	/// <summary>
	/// retrieves, finds and caches target damagehandlers for more
	/// efficient fetching in the future
	/// </summary>
	public static vp_DamageHandler GetDamageHandlerOfCollider(Collider col)
	{

		m_GetDamageHandlerOfColliderResult = null;

		// try to fetch a known damagehandler on this target,
		if (!Instances.TryGetValue(col, out m_GetDamageHandlerOfColliderResult))
		{

			// no damagehandler info on record for this collider: see if we can find
			// one on the transform or any of its ancestors (the lowest ancestor with
			// a damagehandler will be cached as belonging to this collider)
			Transform t = col.transform;
			while ((t != null) && (m_GetDamageHandlerOfColliderResult == null))
			{
				m_GetDamageHandlerOfColliderResult = t.GetComponent<vp_DamageHandler>();
				t = t.parent;
			}

			Instances.Add(col, m_GetDamageHandlerOfColliderResult);		// add result to the dictionary (even if null)

		}

		return m_GetDamageHandlerOfColliderResult;

	}
Exemplo n.º 27
0
	/// <summary>
	/// everything happens in the DoHit method. the script that
	/// spawns the bullet is responsible for setting its position 
	/// and angle. after being instantiated, the bullet immediately
	/// raycasts ahead for its full range, then snaps itself to
	/// the surface of the first object hit. it then spawns a
	/// number of particle effects and plays a random impact sound.
	/// </summary>
	void DoHit()
	{

		Ray ray = new Ray(m_Transform.position, m_Transform.forward);

		// if this bullet was fired by the local player, don't allow it to hit the local player
		if ((m_Source != null) && (m_Source.gameObject.layer == vp_Layer.LocalPlayer))
			LayerMask = vp_Layer.Mask.BulletBlockers;

		// raycast against all big, solid objects except the player itself
		// SNIPPET: using this instead may be useful in cases where bullets
		// fail to hit colliders (however likely at a performance cost)
		//if (Physics.Linecast(m_Transform.position, m_Transform.position + (m_Transform.forward * Range), out hit, LayerMask))
		if (Physics.Raycast(ray, out m_Hit, Range, LayerMask))
		{

			// NOTE: we can't bail out of this if-statement based on !collider.isTrigger,
			// because that would make bullets _disappear_ if they hit a trigger. to make a
			// trigger not interfere with bullets, put it in the layer: 'vp_Layer.Trigger'
			// (default: 27)

			// move this gameobject instance to the hit object
			Vector3 scale = m_Transform.localScale;	// save scale to handle scaled parent objects
			m_Transform.parent = m_Hit.transform;
			m_Transform.localPosition = m_Hit.transform.InverseTransformPoint(m_Hit.point);
			m_Transform.rotation = Quaternion.LookRotation(m_Hit.normal);					// face away from hit surface
			if (m_Hit.transform.lossyScale == Vector3.one)								// if hit object has normal scale
				m_Transform.Rotate(Vector3.forward, Random.Range(0, 360), Space.Self);	// spin randomly
			else
			{
				// rotated child objects will get skewed if the parent object has been
				// unevenly scaled in the editor, so on scaled objects we don't support
				// spin, and we need to unparent, rescale and reparent the decal.
				m_Transform.parent = null;
				m_Transform.localScale = scale;
				m_Transform.parent = m_Hit.transform;
			}
			
			// if hit object has physics, add the bullet force to it
			Rigidbody body = m_Hit.collider.attachedRigidbody;
			if (body != null && !body.isKinematic)
				body.AddForceAtPosition(((ray.direction * Force) / Time.timeScale) / vp_TimeUtility.AdjustedTimeScale, m_Hit.point);

			// spawn impact effect
			if (m_ImpactPrefab != null)
				vp_Utility.Instantiate(m_ImpactPrefab, m_Transform.position, m_Transform.rotation);

			// spawn dust effect
			if (m_DustPrefab != null)
				vp_Utility.Instantiate(m_DustPrefab, m_Transform.position, m_Transform.rotation);

			// spawn spark effect
			if (m_SparkPrefab != null)
			{
				if (Random.value < m_SparkFactor)
					vp_Utility.Instantiate(m_SparkPrefab, m_Transform.position, m_Transform.rotation);
			}

			// spawn debris particle fx
			if (m_DebrisPrefab != null)
				vp_Utility.Instantiate(m_DebrisPrefab, m_Transform.position, m_Transform.rotation);

			// play impact sound
			if (m_ImpactSounds.Count > 0)
			{
				m_Audio.pitch = Random.Range(SoundImpactPitch.x, SoundImpactPitch.y) * Time.timeScale;
				m_Audio.clip = m_ImpactSounds[(int)Random.Range(0, (m_ImpactSounds.Count))];
				m_Audio.Stop();
				m_Audio.Play();
			}

			// do damage if possible
			m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_Hit.collider);	// try to find a damage handler on the target
			if ((m_TargetDHandler != null) && (m_Source != null))
			{
				// this was a known damagehandler target and we know the source: send UFPS damage!
				m_TargetDHandler.Damage(new vp_DamageInfo(Damage, m_Source, vp_DamageInfo.DamageType.Bullet));
			}
			else if (!RequireDamageHandler)
			{
				// this target was known to have no damagehandler: send damage using unitymessage (if allowed)
				m_Hit.collider.SendMessage(DamageMethodName, Damage, SendMessageOptions.DontRequireReceiver);
			}

			// prevent adding decals to objects based on layer
			if ((m_Renderer != null) && NoDecalOnTheseLayers.Length > 0)
			{
				foreach (int layer in NoDecalOnTheseLayers)
				{

					if (m_Hit.transform.gameObject.layer != layer)
						continue;
					m_Renderer.enabled = false;
					TryDestroy();
					return;

				}
			}

			// if bullet is visible (i.e. has a decal), queue it for deletion later
			if(m_Renderer != null)
				vp_DecalManager.Add(gameObject);
			else
				vp_Timer.In(1, TryDestroy);		// we have no renderer, so destroy object in 1 sec

		}
		else
			vp_Utility.Destroy(gameObject);	// hit nothing, so self destruct immediately

	}
Exemplo n.º 28
0
    /// <summary>
    /// everything happens in the DoHit method. the script that
    /// spawns the bullet is responsible for setting its position
    /// and angle. after being instantiated, the bullet immediately
    /// raycasts ahead for its full range, then snaps itself to
    /// the surface of the first object hit. it then spawns a
    /// number of particle effects and plays a random impact sound.
    /// </summary>
    void DoHit()
    {
        Ray ray = new Ray(m_Transform.position, m_Transform.forward);

        // if this bullet was fired by the local player, don't allow it to hit the local player
        if ((m_Source != null) && (m_Source.gameObject.layer == vp_Layer.LocalPlayer))
        {
            LayerMask = vp_Layer.Mask.BulletBlockers;
        }

        // raycast against all big, solid objects except the player itself
        // SNIPPET: using this instead may be useful in cases where bullets
        // fail to hit colliders (however likely at a performance cost)
        //if (Physics.Linecast(m_Transform.position, m_Transform.position + (m_Transform.forward * Range), out hit, LayerMask))
        if (Physics.Raycast(ray, out m_Hit, Range, LayerMask))
        {
            // NOTE: we can't bail out of this if-statement based on !collider.isTrigger,
            // because that would make bullets _disappear_ if they hit a trigger. to make a
            // trigger not interfere with bullets, put it in the layer: 'vp_Layer.Trigger'
            // (default: 27)

            // move this gameobject instance to the hit object
            Vector3 scale = m_Transform.localScale;             // save scale to handle scaled parent objects
            m_Transform.parent        = m_Hit.transform;
            m_Transform.localPosition = m_Hit.transform.InverseTransformPoint(m_Hit.point);
            m_Transform.rotation      = Quaternion.LookRotation(m_Hit.normal);                          // face away from hit surface
            if (m_Hit.transform.lossyScale == Vector3.one)                                              // if hit object has normal scale
            {
                m_Transform.Rotate(Vector3.forward, Random.Range(0, 360), Space.Self);                  // spin randomly
            }
            else
            {
                // rotated child objects will get skewed if the parent object has been
                // unevenly scaled in the editor, so on scaled objects we don't support
                // spin, and we need to unparent, rescale and reparent the decal.
                m_Transform.parent     = null;
                m_Transform.localScale = scale;
                m_Transform.parent     = m_Hit.transform;
            }

            // if hit object has physics, add the bullet force to it
            Rigidbody body = m_Hit.collider.attachedRigidbody;
            if (body != null && !body.isKinematic)
            {
                body.AddForceAtPosition(((ray.direction * Force) / Time.timeScale) / vp_TimeUtility.AdjustedTimeScale, m_Hit.point);
            }

            // spawn impact effect
            if (m_ImpactPrefab != null)
            {
                vp_Utility.Instantiate(m_ImpactPrefab, m_Transform.position, m_Transform.rotation);
            }

            // spawn dust effect
            if (m_DustPrefab != null)
            {
                vp_Utility.Instantiate(m_DustPrefab, m_Transform.position, m_Transform.rotation);
            }

            // spawn spark effect
            if (m_SparkPrefab != null)
            {
                if (Random.value < m_SparkFactor)
                {
                    vp_Utility.Instantiate(m_SparkPrefab, m_Transform.position, m_Transform.rotation);
                }
            }

            // spawn debris particle fx
            if (m_DebrisPrefab != null)
            {
                vp_Utility.Instantiate(m_DebrisPrefab, m_Transform.position, m_Transform.rotation);
            }

            // play impact sound
            if (m_ImpactSounds.Count > 0)
            {
                m_Audio.pitch = Random.Range(SoundImpactPitch.x, SoundImpactPitch.y) * Time.timeScale;
                m_Audio.clip  = m_ImpactSounds[(int)Random.Range(0, (m_ImpactSounds.Count))];
                m_Audio.Stop();
                m_Audio.Play();
            }

            // do damage if possible
            m_TargetDHandler = vp_DamageHandler.GetDamageHandlerOfCollider(m_Hit.collider);             // try to find a damage handler on the target
            if ((m_TargetDHandler != null) && (m_Source != null))
            {
                // this was a known damagehandler target and we know the source: send UFPS damage!
                m_TargetDHandler.Damage(new vp_DamageInfo(Damage, m_Source, vp_DamageInfo.DamageType.Bullet));
            }
            else if (!RequireDamageHandler)
            {
                // this target was known to have no damagehandler: send damage using unitymessage (if allowed)
                m_Hit.collider.SendMessage(DamageMethodName, Damage, SendMessageOptions.DontRequireReceiver);
            }

            // prevent adding decals to objects based on layer
            if ((m_Renderer != null) && NoDecalOnTheseLayers.Length > 0)
            {
                foreach (int layer in NoDecalOnTheseLayers)
                {
                    if (m_Hit.transform.gameObject.layer != layer)
                    {
                        continue;
                    }
                    m_Renderer.enabled = false;
                    TryDestroy();
                    return;
                }
            }

            // if bullet is visible (i.e. has a decal), queue it for deletion later
            if (m_Renderer != null)
            {
                vp_DecalManager.Add(gameObject);
            }
            else
            {
                vp_Timer.In(1, TryDestroy);                             // we have no renderer, so destroy object in 1 sec
            }
        }
        else
        {
            vp_Utility.Destroy(gameObject);             // hit nothing, so self destruct immediately
        }
    }