Jump to content
Unity Insider Forum
GelegenheitsProgrammierer

Auto-Aim-Turret-Problem

Recommended Posts

Hallo Leute,

lange her das ich mich hier mal blicken lassen hab. Doch jetzt bäuchte ich mal wieder eure Hilfe. Das problem ist folgendes:

Ich möchte gerne einen Auto-Aim-Turret haben(die überschrift verrät es ja schon). Dieser soll eine Reichweite haben, was ich mit einem Collider machen möchte und soll sich Ziele rauspicken die er dann anvisiert. Nun da ich hier erst mal nicht das Problem für mich sehe, interessiert und das erst mal nicht.

Mein Tower ist wie folgt auf gebaut. Ich habe denTurm als model und dann noch die Kanone bzw die waffe. Die waffe ist ein Child von dem Turm. Soweit so gut.

Nun möchte ich da der Turm ein einzelnes Testziel anvisiert. Ich hab das erst mal so gelöst.

public float speed = 3.0f;
 
    GameObject m_target;
    Vector3 m_lastKnownPosition = Vector3.zero;
    Quaternion m_lookAtRotation;
 
    // Update is called once per frame
    void Update () {
        if(m_target){
            if(m_lastKnownPosition != m_target.transform.position){
                m_lastKnownPosition = m_target.transform.position;
                m_lookAtRotation = Quaternion.LookRotation(m_lastKnownPosition - transform.position);
            }
 
            if(transform.rotation != m_lookAtRotation){
                transform.rotation = Quaternion.RotateTowards(transform.rotation, m_lookAtRotation, speed * Time.deltaTime);
            }
        }
    }

War jetzt erst mal nicht so schwer. Nun wollte ich das der Turm sich nur auf der Y-axe gedreht wird und die Kanone auf der x-Axe. Auch das hab ih relativ unschön gelöst bekommen aber es mehr oder weniger genau geklappt. Doch dann bin ich weiter gegangen, denn ich will den Turret begrenzen, was den Drehwinkel angeht. Und genau da liegt jetzt mein Problem, den alles was ich ausprobiert. Ich hab mir gedacht das mit clamp zu tun doch bei Quaternion ist das so ne sache. Mir kommt es so vor das der Ansatz den ich gewählt habe für mein Problem nicht wirklich geignet ist.

Meine Frage ist hättet ihr da ne mögliche Lösung oder andere Ansätze. Die ergebnisse meiner Google suche waren eher schwammig und führen auch nicht immer zum Ergebnis.

 

Hoffe ich konnte mein Problem deutlich darstellen und ihr könnt mir weiterhelfen.

Mit freundlichen Grüßen

Gelegenheitsprogrammierer

Share this post


Link to post
Share on other sites

Da habe ich einen lustigen Trick für dich:

var targetRotation = Quaternion.LookRotation(direction);

So weit, so gut. Und dann:

targetRotation = Quaternion.RotateTowards(Quaternion.identity, targetRotation, maxAngle);

Quaternion.RotateTowards dreht das erste Quaternion in Richtung des zweiten, aber maximal maxAngle weit. Wenn targetRotation also weiter weg gedreht ist als maxAngle Grad, dann wird nur maxAngle weit in diese Richtung gedreht. Damit begrenzt du das. Die Funktion gibt das gedrehte Quaternion zurück, und dann wird es zur neuen targetRotation.

Quaternion.identity ist die Ausgangsrotation, also 0,0,0 in Eulerwinkeln ausgedrückt. Damit das hier damit funktioniert, willst du in der letzten Zeile vermutlich Transform.localRotation statt Transform.rotation benutzen.

  • Like 1

Share this post


Link to post
Share on other sites

So ich hab das Problem jetzt endlich lösen können, wenn man draufkommt ist es gar nicht so schwer. Naja

Danke dir erst mal Sascha. Irgendwie hat das was du Vorgeschlagen hast nicht funktioniert oder ich hatte deine Idee nicht gerafft(wahrscheinlicher).

Hier mal mein Code, wie es jetzt funktioniert.

public class TurretContr : MonoBehaviour
{
    //Geschwindigkeit der Drehung
    public float RotateSpeed = 3.0f;
    //Das Target was anvisiert werden soll
    public GameObject activeTarget;

    //Die Zielerfassung
    public GameObject TargetAcquisition;
    //Die Basis des Turms
    public GameObject Base;
    //Min und Max rotation des Turm auf der y achse
    public Vector2 BaseMinMax;
    //Waffe des Turms
    public GameObject Weapon;
    //Min und Max rotation der Waffe auf der x Achse
    public Vector2 WeaponMinMax;

    //Temporäre rotation zu Ziel
    private Quaternion AcquisitionRotation;

    // Update is called once per frame
    void Update()
    {
        RotateTargetAcquisition();
        OrientateTurret();
    }

    void RotateTargetAcquisition()
    {
        //Debug.Log(Base.transform.localEulerAngles + " / " + Weapon.transform.localEulerAngles + " / " + TargetAcquisition.transform.localEulerAngles);
        //Um die Richtung des Targets als Quaternion zu bekommen
        AcquisitionRotation = Quaternion.LookRotation(activeTarget.transform.position);
        //Annähern des Targets
        AcquisitionRotation = Quaternion.RotateTowards(TargetAcquisition.transform.rotation, AcquisitionRotation, RotateSpeed * Time.deltaTime);
        //Die Rotation setzen
        TargetAcquisition.transform.localEulerAngles = AcquisitionRotation.eulerAngles;
        //Die Rotation begrenzen
        TargetAcquisition.transform.localEulerAngles = new Vector3(ClampEulerAngle(TargetAcquisition.transform.localEulerAngles.x, WeaponMinMax.x, WeaponMinMax.y), ClampEulerAngle(TargetAcquisition.transform.localEulerAngles.y, BaseMinMax.x, BaseMinMax.y), 0);
    }

    /// <summary>
    /// die Modelle Ausrichten
    /// </summary>
    void OrientateTurret()
    {
        Base.transform.localEulerAngles = new Vector3(0,TargetAcquisition.transform.localEulerAngles.y,0);
        Weapon.transform.localEulerAngles = new Vector3(TargetAcquisition.transform.localEulerAngles.x, 0,0);
    }

    /// <summary>
    /// Clampfunktion für eulerangles
    /// </summary>
    /// <param name="_angle"></param>
    /// <param name="_min"></param>
    /// <param name="_max"></param>
    /// <returns></returns>
    float ClampEulerAngle(float _angle, float _min, float _max)
    {
        float tempAngle = _angle;
        if(_angle < 180)
        {
            tempAngle = Mathf.Clamp(tempAngle,0,_max);
        }
        else
        {
            tempAngle = Mathf.Clamp(tempAngle, 360 - _min, 360);
        }

        return tempAngle;
    }
}

Hoffe es kann jemanden helfen.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×