Jump to content
Unity Insider Forum

Follower und zu gleich Attacker wenn Enemy in Nähe


kevios105

Recommended Posts

Hallo :) 
ich hab folgende frage und zwar wie mache ich das am besten mit meinem vorhanden Script das wenn ein Enemy bzw. Gegner in die Nähe von meinem Follower kommt,
ein Follower automatisch diesen Gegner angreift und sobald dieser Tot ist wieder meinem Player folgt oder aber auch wenn mein Player weg läuft (also eine gewisse Distanz zu Follower und Player entsteht), der Follower sich automatisch dazu entscheidet dem Player wieder zufolgen...

Ich bin ziemlich neu in Unity und C# deshalb weiß ich ehrlich gesagt nicht einmal wo ich ansetzen könnte schon allein wegen dem abwiegen von Prioitäten von Player zu Gegner ...
Dann hatte ich überlegt das ganze mit einem SphereCollider zu lösen, aber habe hier dann erfahren das wenn ich irgendwann mal mehrere Follower habe es ganz schön Laggen könnte usw und das dies keine gute Lösung wäre... Ist das richtig?

Ich hoffe ich konnte mein Problem einigermaßen gut beschreiben und es wäre wirklich toll wenn mir da jemand helfen könnte, da ich schon in anderen Foren zuvor dieses Problem beschrieben hatte und keinerlei Hilfe bekommen habe 

Hier mein vorhandenes Script bisher:
 

using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
using System;


public class Petfollower : MonoBehaviour 
{

public Transform Player; 
public float rotationSpeed = 3; //speed of turning
public GameObject Follower;
public float distance = 1.3f;
public float followDistance = 1.4f;
public bool isNotDead = true;
bool stopped = false;

private Transform myTransform; 
private UnityEngine.AI.NavMeshAgent agent; //current transform data of this enemy

void Awake()
{
	myTransform = transform; //cache transform data for easy access/preformance
}

void Start()
{
	agent = GetComponent<UnityEngine.AI.NavMeshAgent>();

}

void Update () {

	if(isNotDead){

		//rotate to look at the player
		var distance = Vector3.Distance(Player.position, myTransform.position) ;
		if (distance < followDistance) {
			stopped = true;
			GetComponent<Animator>().Play("Idle");
		}

		else{   
			//move towards the player
			stopped = false;
			agent.SetDestination(Player.position);
			GetComponent<Animator>().Play("Walk");
			myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
				Quaternion.LookRotation(Player.position - myTransform.position), rotationSpeed*Time.deltaTime);
		}
	}
}
}

Bitte helft mir das wäre so wundervoll und ich könnte meine Kopfschmerzen endlich beseitigen :D

Link zu diesem Kommentar
Auf anderen Seiten teilen

Also ich gebe echt mein bestes bin aber echt am verzweifeln :( ich benutze das Addon Invector und es klappt rein gar nichts >.< bitte kann mir jemand mal helfen ...

Hier mein bisheriger Code:

using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
using System;
using Invector.EventSystems;


public class PetfollowerAttack1 : MonoBehaviour 
{

public Transform Player; 
public float rotationSpeed = 3; //speed of turning
public GameObject Follower;
public float distance = 1.3f;
public float followDistance = 1.4f;
public bool isNotDead = true;
bool stopped = false;
	public GameObject territory;
	GameObject Enemy;




private Transform myTransform; 
private UnityEngine.AI.NavMeshAgent agent; //current transform data of this enemy

void Awake()
{
	myTransform = transform; //cache transform data for easy access/preformance
}

void Start()
{
	agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
		Enemy =  GameObject.FindGameObjectWithTag("Enemy");

}

void Update () {

	if(isNotDead){

		//rotate to look at the player
		var distance = Vector3.Distance(Player.position, myTransform.position) ;
		if (distance < followDistance) {
			stopped = true;
			GetComponent<Animator>().Play("Idle");
		}

		else{   
			//move towards the player
			stopped = false;
			agent.SetDestination(Player.position);
			GetComponent<Animator>().Play("Walk");
			myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
				Quaternion.LookRotation(Player.position - myTransform.position), rotationSpeed*Time.deltaTime);
		}
	}
	}
		


		void OnTriggerEnter (Collider other)
		{
		var distance = Vector3.Distance(Enemy, myTransform.position) ;
		if (other.gameObject.tag == Enemy)
			{
				agent.SetDestination(Enemy);
				GetComponent<Animator>().Play("Walk");
				myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
					Quaternion.LookRotation(Enemy - myTransform.position), rotationSpeed*Time.deltaTime);
		
		}
		void ApplyDamage (){
				vIDamageReceiver ISerializationCallbackReceiver = Follower.GetComponent<vIDamageReceiver>();
				if (receiver != null)
					receiver.TakeDamage(45);
			}

		}

		void OnTriggerExit (Collider other)
		{
		if (other.gameObject.tag == Enemy) 
			{
				agent.SetDestination(Player.position);
				GetComponent<Animator>().Play("Walk");
				myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
					Quaternion.LookRotation(Player.position - myTransform.position), rotationSpeed*Time.deltaTime);			}
		}


}

Ich wäre bei jeder Hilfe euch soooo dermaßen Dankbar!!!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wäre gut, wenn du dich selber mehr mit Unity beschäftigst, weil ich werde auch keine fertigen Skripte hier posten. Dafür aber ein paar Ansätze.

1) Ein Enum-Variable für den Zustand deines AI Skriptes wäre sinnvoll, siehe:
https://unity3d.com/de/learn/tutorials/topics/scripting/enumerations
Hier ein Beispiel:

private enum AIState { Idle, Detect, Patrol, Chase, Follow, Attack}

2) Ein Sphere-Trigger-Collider um den Spieler oder um den Begleiter ist eine sinnvolle Lösung, um Feinde die in der Nähe sind zu erkennen.
3) Wird ein Feind in Spieler (oder Begleiternähe) erkannt, dann sollte der Begleiter in den Zustand "Chase" (Verfolgen) wechseln.
Erreicht der Begleiter eine nahe Distanz zum Feind, dann sollte er in den Zustand "Attack" (Angriff) übergeben. Hier könnte dann eine Angriffanimation abgespielt werden.
4) Ist der Feind getötet, geht der Begleiter wieder in den Zustand "Idle".
5) Wird der Abstand zwischen Begleiter und Spieler zu groß, dann geht der Begleiter in den Zustand "Follow".

Ich schreibe mal deinen bisherigen Code dahingehend um, weitere Zustände solltest du aber selber einbauen.
Das ist nur ein grober Anfang. Schaden erzeugen usw. am Feind habe ich nur ansatzweise eingebaut. Aber du hast nun eine gute Struktur und siehst wie man einen Zustand verwalten kann. Auch die Zustandsübergänge in der Update-Methode sind noch unvollständig. Diese musst du je nach Zustand noch entsprechend erweitern.

using UnityEngine;
using System.Collections;
using System;
//using Invector.EventSystems;


public class PetfollowerAttack : MonoBehaviour
{

    public Transform Player;
    public float rotationSpeed = 3; //speed of turning
    public GameObject Follower;
    public float distance = 1.3f;
    public float followDistance = 1.4f;
    public float attackDistance = 2.0f;
    public bool isNotDead = true;
    bool stopped = false;
    public GameObject territory;
    GameObject Enemy;

    private Transform myTransform;
    private NavMeshAgent agent; //current transform data of this enemy
    private enum AIState { Idle, Detect, Patrol, Chase, Follow, Attack } //holds AI states
    private AIState currentState;

    void Awake()
    {
        myTransform = transform; //cache transform data for easy access/preformance
        currentState = AIState.Idle;
    }

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {

        if (isNotDead)
        {
            float distance;
            switch (currentState)
            {
                case AIState.Idle:
                    Debug.Log("State: Idle.");
                    distance = Vector3.Distance(Player.position, myTransform.position);
                    if (distance > followDistance) FollowPlayer();
                    break;
                case AIState.Follow:
                    Debug.Log("State: Follow Player.");
                    distance = Vector3.Distance(Player.position, myTransform.position);
                    if (distance < followDistance) Idle();
                    break;
                case AIState.Chase:
                    Debug.Log("State: Chasing Enemy.");
                    break;
                case AIState.Attack:
                    Debug.Log("State: Attacking Enemy.");
                    break;
                default:
                    Debug.Log("State: Unknown State.");
                    break;
            }

        }
    }

    void Idle()
    {
        //stopped = true;
        currentState = AIState.Idle;
        agent.Stop();
        GetComponent<Animator>().Play("Idle");
    }

    void FollowPlayer()
    {
        // Move towards the player
        // stopped = false;
        currentState = AIState.Follow;
        agent.Resume();
        agent.SetDestination(Player.position);
        GetComponent<Animator>().Play("Walk");
        myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(Player.position - myTransform.position), rotationSpeed * Time.deltaTime);
    }

    void ChaseEnemy(GameObject enemy)
    {
        currentState = AIState.Chase;
        agent.Resume();
        agent.SetDestination(enemy.transform.position);
        GetComponent<Animator>().Play("Walk");
        myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(enemy.transform.position - myTransform.position), rotationSpeed * Time.deltaTime);

        var distance = Vector3.Distance(enemy.transform.position, myTransform.position);          
        if (distance < attackDistance) AttackEnemy(enemy);
    }

    void AttackEnemy(GameObject enemy)
    {
        currentState = AIState.Attack;
        agent.SetDestination(enemy.transform.position);
        GetComponent<Animator>().Play("Attack"); // Attack animation
        myTransform.rotation = Quaternion.Slerp(myTransform.rotation, Quaternion.LookRotation(enemy.transform.position - myTransform.position), rotationSpeed * Time.deltaTime);
        // ! Do damage to the enemy here !
    }

    void OnTriggerEnter(Collider other)
    {
        //var distance = Vector3.Distance(Enemy, myTransform.position);
        if (other.CompareTag("Enemy"))
        {
            ChaseEnemy(other.gameObject);
        }

        /*
        void ApplyDamage (){
            vIDamageReceiver ISerializationCallbackReceiver = Follower.GetComponent<vIDamageReceiver>();
            if (receiver != null)
                receiver.TakeDamage(45);
        }*/
    }

    void OnTriggerExit(Collider other)
    {
        if (other.CompareTag("Enemy"))
        {
            Idle();
        }
    }

}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Erst einmal vielen Lieben DANK!!!

nun versteh ich das ganze auch etwas besser wie es funktioniert!
Ein Problem bleibt aber und zwar das der Begleiter am Anfang zum Spieler hin läuft, bewegt sich der Spieler aber weg bleibt der Begleiter an der Stelle und spielt nur die Animation "Walk" ab. Auch Routiert der Begleiter nicht zum Spieler sondern hält die Richtung bei.

Könntest du mir bitte hierbei noch einmal helfen?

Den Rest bekomme ich hoffentlich dann selbst noch alles hin... :) 

 

PS: bin wirklich fleißig am lernen von C# ... les mir im moment einfach alles durch was ich in die finger bekomme! :) 

 

///EDIT

ICH HABS!!!! DANKE DANKE :):) 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...