help with damage indicator script

Hi to all i need some help with my damage indicator script i’m using in my prototype template…

pratically the indicator seems to not set correct orgiin attack direction as you can see in the jpg

[](http://)

here the code

using UnityEngine;
using System.Collections;

public class DamageIndicator : MonoBehaviour {

    /// <summary>
    /// Attack from direction
    /// </summary>
    [HideInInspector]
    public Vector3 attackDirection;
    /// <summary>
    /// time reach for fade arrow
    /// </summary>
    public float FadeTime = 3;
    public Texture damageIndicatorTexture;
    public Color ArrowColor = new Color(0.85f, 0, 0);
    /// <summary>
    /// the transform root of player
    /// </summary>
    public Transform target;
    //Private
    public Vector2 pivotPoint;
    public float alpha = 0.0f;
    public float offset = 350f;
    public float rotationOffset;

    /// <summary>
    ///
    /// </summary>
    void OnGUI()
    {
        if (this.alpha > 0)
        {
            this.offset = Screen.height / 4;
            GUI.color = new Color(ArrowColor.r, ArrowColor.g, ArrowColor.b, this.alpha);
            Vector2 vector = new Vector2(((Screen.width / 2) - (this.damageIndicatorTexture.width / 2)), (Screen.height / 2) - this.offset);
            this.pivotPoint = new Vector2((Screen.width / 2), (Screen.height / 2));
            GUIUtility.RotateAroundPivot(this.rotationOffset, this.pivotPoint);
            GUI.DrawTexture(new Rect(vector.x, vector.y, this.damageIndicatorTexture.width, this.damageIndicatorTexture.height), this.damageIndicatorTexture);
        }
    }

    /// <summary>
    /// Use this to send a new direction of attack
    /// </summary>
    /// <param name="dir">postion of attacker</param>
    public void AttackFrom(Vector3 dir)
    {
        //target = this.transform ;
        this.attackDirection = dir;
        this.alpha = 3f;
    }
    /// <summary>
    /// if this is visible Update position
    /// </summary>
    void Update()
    {
        if (this.alpha > 0)
        {
            this.alpha -= Time.deltaTime;
            this.UpdateDirection();
        }
    }
    /// <summary>
    /// update direction as the arrow shows
    /// </summary>
    void UpdateDirection()
    {
        Vector3 rhs = this.attackDirection - this.target.position;
        rhs.y = 0;
        rhs.Normalize();
        Vector3 forward;
        if (Camera.main != null)
        {
            forward = Camera.main.transform.forward;
        }
        else
        {
            if (Camera.current != null)
            {
                forward = Camera.current.transform.forward;
            }
            else
            {
                forward = this.transform.forward;
            }
        }
        float GetPos = Vector3.Dot(forward, rhs);
        if (Vector3.Cross(forward, rhs).y > 0)
        {
            this.rotationOffset = (1f - GetPos) * 90;
        }
        else
        {
            this.rotationOffset = (1f - GetPos) * -90;
        }
    }
}

no one could try help me??

@JC_LEON

Well… I tried to already help in Answers… maybe continue there?

yes and i thanks to oyu very much but sincerly i cannot figure the system you are trying to set for me
i really dont know ho to correcly set up the part of code you wrote for me and i’m not able t ocorreclty understand your reply… and to correcly call the method when needed…

@JC_LEON - Did you actually check the latest update? I updated the code… so it’s basically plug and play.

yes and i made this script

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class IndicatorDamage : MonoBehaviour
{
    public RectTransform indicator;
    public Transform otherTransform;
    public Transform player;
    public bool useDirection;
    float angle = 0;

    void Update()
    {
        if (useDirection)
        {
            // Angle based on the direction of the shooter relative to player
            angle = GetHitAngle(player, otherTransform.forward);
            indicator.rotation = Quaternion.Euler(0, 0, -angle);
        }
        else if (!useDirection)
        {
            // Angle taken from other objects pos and player
            angle = GetHitAngle(player, (player.position - otherTransform.position).normalized);
            indicator.rotation = Quaternion.Euler(0, 0, -angle);
        }
    }

    public float GetHitAngle(Transform player, Vector3 incomingDir)
    {
        // Flatten to plane
        var otherDir = new Vector3(-incomingDir.x, 0f, -incomingDir.z);
        var playerFwd = Vector3.ProjectOnPlane(player.forward, Vector3.up);

        // Direction between player fwd and incoming object
        var angle = Vector3.SignedAngle(playerFwd, otherDir, Vector3.up);

        return angle;
    }
}

i attached to my player gameobject and filled the field into inspector but i cannot figure if in "other transform "field i need to put the damade handler object or what else?

I’ll post the code I put in the answers;

Here are the variables you need.

public RectTransform indicator; // Indicator, an image on canvas.
public Transform otherTransform; // Your other object, in case you use position of firing as source
public Transform player; // your player transform.
public bool useDirection; // Only needed for demo.
float angle = 0;

If you want to use direction of bullet / arrow, you’ll use this code I wrote:

// Angle based on direction the of shooter relative to player
angle = GetHitAngle(player, otherTransform.forward);
indicator.rotation = Quaternion.Euler(0,0, -angle);

You can replace the “otherTransform.forward” with your direction of incoming bullet.

If you want to use enemy position on event when bullet / arrow hit player to detect direction, use this:

// Angle between other pos vs player
angle = GetHitAngle(player, (player.position - otherTransform.position).normalized);
indicator.rotation = Quaternion.Euler(0,0, -angle);

Note how in the GetHitAngle I changed the player vs enemy (other object) positions into directions to make it work for GetHitAngle.

This is the method, works for both cases:

public float GetHitAngle (Transform player, Vector3 incomingDir)
{
    // Flatten to plane
    var otherDir = new Vector3(-incomingDir.x, 0f, -incomingDir.z);
    var playerFwd = Vector3.ProjectOnPlane(player.forward, Vector3.up);

    // Direction between player fwd and incoming object
    var angle = Vector3.SignedAngle(playerFwd, otherDir, Vector3.up);
 
    return angle;
}

This should be pretty understandable I think.

I didn’t test it too much, but I tested both angle detection methods and these should work if you move and rotate player so that he is no longer aligned to world axis.

I also have some other code, that will use the angle (that’s why I used SignedAngle) to make direction indicator only show L/R/U/D so that player don’t have exact direction info.

MANY MANY THANKS…i’ll try to figure it but…if i dont have only a specific damage handler and wantto player show damaga inciatator every timeit gets damaged i need to specify the “other Transform” anyway?