[C#] New SeekSteer

Cette section est destinée aux scripts partagés par la communauté. Chaque post est destiné à un script. Suivez bien les recommandations.
Avatar de l’utilisateur
ZJP
Messages : 5745
Inscription : 15 Déc 2009 06:00

[C#] New SeekSteer

Message par ZJP » 04 Mars 2017 21:11

Salut,

Le SeekSteer du Wiki est l'un des scripts de WayPoint le plus connu.
Cependant, après l'avoir essayé, j'y ai trouvé quelques manques (cela reste après tout une version minimaliste :mrgreen: ) du point de vu performance et fonctionnalité. Le script présenté (tout en restant une version de base) est une évolution/amélioration du script original.


- NOM DU SCRIPT : NewSeekSteer
- AUTEUR : ZJP (voir la version original pour le "concept")
- DESCRIPTION : Script de déplacement par WayPoints, plus options de détection d'une "cible" en fonction de son angle de vue, sa distance et d'un obstacle présent. (Usage de RotateTowards à la place du Lerp.)
Le script intègre aussi la notion de délai de réaction du perso avec pour effet secondaire de réduire le nombre de calculs effectués.

- UTILISATION :
a) Coller le script sur un GO (avec ou sans RigidBody)
b) Ajouter un GO cible.
c) Ajouter une série de GO Waypoints.
d) Mettez à jour les paramètres du script.

Code : Tout sélectionner

// NewSeekSteer.cs
using UnityEngine;
using System.Collections;

public class NewSeekSteer : MonoBehaviour {
	public Transform[] waypoints;
	public float waypointRayonDetection = 1.5f;

	public bool moveMe  = true;
	public Transform myTarget;
	[Range (1,10)] public int delaiReaction = 10;           // delai du "temps reaction" du perso
	[Range (20.0f,180.0f)] public float AngleDeVue = 90.0f; // Angle de vu. 20 à 180 degrés
	[Range (1.0f ,200.0f)] public float DistanceDeVue = 100.0f;
	private int timeReaction = 0; 


	public float speed    = 2.0f; // Vitesse de progression
	public float rotSpeed = 2.0f; // Vitesse de rotation

	private int targetwaypoint;
	private Transform xform;
	private Vector3 TargetDir      = new Vector3(0.0f,0.0f, 0.0f);
	private float DetectAngle      = 0.0f;
	private float waypointDistance = 1.0f;
	private bool seeYou = false;
//	private Rigidbody rigBody;

	protected void Start() {
		//rigBody = GetComponent<Rigidbody>();
		xform = transform;
		if(waypoints.Length <= 0){
			Debug.Log("Pas de waypoints");
			enabled = false; // déactivation du script
		}
		targetwaypoint = 0;
	}

    protected void FixedUpdate()
	{

		if(waypoints.Length <= 0) return; // pas de WP
		if (!moveMe) return;

		timeReaction++;
		if (timeReaction > delaiReaction) // en plus d'ajouter un temps de reaction au perso , permet de reduire le nombre de calculs effectués
		{
			TargetDir = waypoints[targetwaypoint].position - xform.position;
			//TargetDir.y = 0.0f; // peut être figé !!!
			TargetDir = Vector3.RotateTowards( xform.forward, TargetDir, rotSpeed * Time.fixedDeltaTime, 0.0f );
			// version Transform !!! *********************************************************************
			xform.rotation = Quaternion.LookRotation(TargetDir);
			// version Physic !!!! ***********************************************************************
			//rigBody.MoveRotation(Quaternion.LookRotation(TargetDir));
		
			// Changement de WayPoint *******************************************************************************
			waypointDistance = Vector3.Distance(xform.position, waypoints[targetwaypoint].position);
			if(waypointDistance <= waypointRayonDetection)
			{
				targetwaypoint++;
				if(targetwaypoint >= waypoints.Length) targetwaypoint = 0;
				//targetwaypoint = (targetwaypoint + 1) % waypoints.Length;
			}
			// Changement de WayPoint *******************************************************************************

			// cible en vue?! ***************************************************************************************
			seeYou = false;
			if ( DistanceDeVue > Vector3.Distance(xform.position, myTarget.position) ) // Bonne distance
			{
				DetectAngle = 1.0f - Vector3.Dot( xform.forward, ( myTarget.position - xform.position ).normalized);
				if (DetectAngle < AngleDeVue / 2.0f * 0.0111f) // Bon angle de vue
				{
					if (!Physics.Linecast( xform.position, myTarget.position )) seeYou = true; // Pas d'obstacle
				}
			}
			// cible en vue?! ***************************************************************************************
			timeReaction = 0;
		}
		xform.position = xform.position + xform.forward * Time.fixedDeltaTime * speed; // version transform
		//rigBody.MovePosition(xform.position + xform.forward * Time.fixedDeltaTime * speed ); // version physic
	}

	// draws red line from waypoint to waypoint
	public void OnDrawGizmos() {
		Gizmos.color = Color.red;
		if(waypoints == null) return;
		for(int i = 0; i < waypoints.Length; i++){
			Vector3 pos = waypoints[i].position;
			if(i > 0){
				Vector3 prev = waypoints[i-1].position;
				Gizmos.DrawLine(prev,pos);
			}
		}
		Gizmos.DrawLine(waypoints[0].position , waypoints[waypoints.Length-1].position);
		// ligne entre NPC et Cible
		if (seeYou)	{
			Gizmos.color = Color.white;
			Gizmos.DrawLine(xform.position, myTarget.position);
		}
	}
}

Dernière édition par ZJP le 16 Avr 2017 05:46, édité 4 fois.

Avatar de l’utilisateur
Franck
Bricoleur
Bricoleur
Messages : 2884
Inscription : 08 Jan 2011 18:43
Localisation : Tours

Re: [C#] New SeekSteer

Message par Franck » 05 Mars 2017 12:39

Merci JP. :)
Dés fois j'bug, dés fois j'bug pas.

Avatar de l’utilisateur
ZJP
Messages : 5745
Inscription : 15 Déc 2009 06:00

Re: [C#] New SeekSteer

Message par ZJP » 06 Mars 2017 06:14

Franck a écrit :Merci JP. :)
A ton service. ;-)

Avatar de l’utilisateur
E3DStef
Administrateur
Administrateur
Messages : 1646
Inscription : 14 Juil 2013 18:30
Localisation : https://www.carte-des-membres.com/fr/Unity3D-France/

Re: [C#] New SeekSteer

Message par E3DStef » 08 Mars 2017 00:46

yess ! +1
Le Savoir n'est Précieux que s'il est Partagé

Si besoin urgent de me contacter, faites moi un mail sur : franceunity3d@gmail.com

Répondre

Revenir vers « Scripts »