HeadLookController3

Лучший способ помочь другим, поделиться своими находками.

HeadLookController3

Сообщение 6opoDuJI0 22 мар 2010, 18:01

Улучшенный вариант HeadLookController'а выложенного на офф. комьюнити
с этим скриптом вашу модель никогда не перекрутит как змею,а только будет смотреть туда,куда надо :D
использование - подобно обычному HeadLookController'у только в переменную TargetNode нужно установить трансформ за которым должен следить ваш человечек
используется тут :
viewtopic.php?f=17&t=1312&st=0&sk=t&sd=a&start=45#p15267
код
Код: Выделить всё
using UnityEngine;
using System.Collections;

[System.Serializable]
public class Bending_Segment {
   public Transform firstTransform;
   public Transform lastTransform;
   public float thresholdAngleDifference = 0;
   public float bendingMultiplier = 0.6f;
   public float maxAngleDifference = 30;
   public float maxBendingAngle = 80;
   public float responsiveness = 5;
   internal float angleH;
   internal float angleV;
   internal Vector3 dirUp;
   internal Vector3 referenceLookDir;
   internal Vector3 referenceUpDir;
   internal int chainLength;
   internal Quaternion[] origRotations;
}

[System.Serializable]
public class Non_Affected_Joints {
   public Transform joint;
   public float effect = 0;
}

public class HeadLookController3 : MonoBehaviour {
   
   public Transform rootNode;
   public Bending_Segment[] segments;
   public Non_Affected_Joints[] Non_Affected_Joints;
   public Vector3 headLookVector = Vector3.forward;
   public Vector3 headUpVector = Vector3.up;
   public Vector3 target = Vector3.zero;
   public Quaternion targrot;
   public Transform TargetNode;
   public float effect = 1;
   public bool overrideAnimation = false;
   public bool LocalPlayer =false;
   
   void Start () {
      
      LocalPlayer=true;
      
      
      if (rootNode == null) {
         rootNode = transform;
      }
      
      // Setup segments
      foreach (Bending_Segment segment in segments) {
         Quaternion parentRot = segment.firstTransform.parent.rotation;
         Quaternion parentRotInv = Quaternion.Inverse(parentRot);
         segment.referenceLookDir =
            parentRotInv * rootNode.rotation * headLookVector.normalized;
         segment.referenceUpDir =
            parentRotInv * rootNode.rotation * headUpVector.normalized;
         segment.angleH = 0;
         segment.angleV = 0;
         segment.dirUp = segment.referenceUpDir;
         
         segment.chainLength = 1;
         Transform t = segment.lastTransform;
         while (t != segment.firstTransform && t != t.root) {
            segment.chainLength++;
            t = t.parent;
         }
         
         segment.origRotations = new Quaternion[segment.chainLength];
         t = segment.lastTransform;
         for (int i=segment.chainLength-1; i>=0; i--) {
            segment.origRotations[i] = t.localRotation;
            t = t.parent;
         }
      }
   }
   
   
   
   
   void LateUpdate () {
   
   target=TargetNode.position;
   
   
   
      if (Time.deltaTime == 0)
         return;
      
      // Remember initial directions of joints that should not be affected
      Vector3[] jointDirections = new Vector3[Non_Affected_Joints.Length];
      for (int i=0; i<Non_Affected_Joints.Length; i++) {
         foreach (Transform child in Non_Affected_Joints[i].joint) {
            jointDirections[i] = child.position - Non_Affected_Joints[i].joint.position;
            break;
         }
      }
      
      // Handle each segment
      foreach (Bending_Segment segment in segments) {
         Transform t = segment.lastTransform;
         if (overrideAnimation) {
            for (int i=segment.chainLength-1; i>=0; i--) {
               t.localRotation = segment.origRotations[i];
               t = t.parent;
            }
         }
         
         Quaternion parentRot = segment.firstTransform.parent.rotation;
         Quaternion parentRotInv = Quaternion.Inverse(parentRot);
         
         // Desired look direction in world space
         Vector3 lookDirWorld = (target - segment.lastTransform.position).normalized;
         
         // Desired look directions in neck parent space
         Vector3 lookDirGoal = (parentRotInv * lookDirWorld);
         
         // Get the horizontal and vertical rotation angle to look at the target
         float hAngle = AngleAroundAxis(
            segment.referenceLookDir, lookDirGoal, segment.referenceUpDir
         );
         
         Vector3 rightOfTarget = Vector3.Cross(segment.referenceUpDir, lookDirGoal);
         
         Vector3 lookDirGoalinHPlane =
            lookDirGoal - Vector3.Project(lookDirGoal, segment.referenceUpDir);
         
         float vAngle = AngleAroundAxis(
            lookDirGoalinHPlane, lookDirGoal, rightOfTarget
         );
         
         // Handle threshold angle difference, bending multiplier,
         // and max angle difference here
         float hAngleThr = Mathf.Max(
            0, Mathf.Abs(hAngle) - segment.thresholdAngleDifference
         ) * Mathf.Sign(hAngle);
         
         float vAngleThr = Mathf.Max(
            0, Mathf.Abs(vAngle) - segment.thresholdAngleDifference
         ) * Mathf.Sign(vAngle);
         
         hAngle = Mathf.Max(
            Mathf.Abs(hAngleThr) * Mathf.Abs(segment.bendingMultiplier),
            Mathf.Abs(hAngle) - segment.maxAngleDifference
         ) * Mathf.Sign(hAngle) * Mathf.Sign(segment.bendingMultiplier);
         
         vAngle = Mathf.Max(
            Mathf.Abs(vAngleThr) * Mathf.Abs(segment.bendingMultiplier),
            Mathf.Abs(vAngle) - segment.maxAngleDifference
         ) * Mathf.Sign(vAngle) * Mathf.Sign(segment.bendingMultiplier);
         
         // Handle max bending angle here
         hAngle = Mathf.Clamp(hAngle, -segment.maxBendingAngle, segment.maxBendingAngle);
         vAngle = Mathf.Clamp(vAngle, -segment.maxBendingAngle, segment.maxBendingAngle);
         
         Vector3 referenceRightDir =
            Vector3.Cross(segment.referenceUpDir, segment.referenceLookDir);
         
         // Lerp angles
         segment.angleH = Mathf.Lerp(
            segment.angleH, hAngle, Time.deltaTime * segment.responsiveness
         );
         segment.angleV = Mathf.Lerp(
            segment.angleV, vAngle, Time.deltaTime * segment.responsiveness
         );
         
         // Get direction
         lookDirGoal = Quaternion.AngleAxis(segment.angleH, segment.referenceUpDir)
            * Quaternion.AngleAxis(segment.angleV, referenceRightDir)
            * segment.referenceLookDir;
         
         // Make look and up perpendicular
         Vector3 upDirGoal = segment.referenceUpDir;
         Vector3.OrthoNormalize(ref lookDirGoal, ref upDirGoal);
         
         // Interpolated look and up directions in neck parent space
         Vector3 lookDir = lookDirGoal;
         segment.dirUp = Vector3.Slerp(segment.dirUp, upDirGoal, Time.deltaTime*5);
         Vector3.OrthoNormalize(ref lookDir, ref segment.dirUp);
         
         // Look rotation in world space
         Quaternion lookRot = (
            (parentRot * Quaternion.LookRotation(lookDir, segment.dirUp))
            * Quaternion.Inverse(
               parentRot * Quaternion.LookRotation(
                  segment.referenceLookDir, segment.referenceUpDir
               )
            )
         );
         
         // Distribute rotation over all joints in segment
         Quaternion dividedRotation =
            Quaternion.Slerp(Quaternion.identity, lookRot, effect / segment.chainLength);
         t = segment.lastTransform;
         for (int i=0; i<segment.chainLength; i++) {
            t.rotation = dividedRotation * t.rotation;
            t = t.parent;
         }
      }
      
      // Handle non affected joints
      for (int i=0; i<Non_Affected_Joints.Length; i++) {
         Vector3 newJointDirection = Vector3.zero;
         
         foreach (Transform child in Non_Affected_Joints[i].joint) {
            newJointDirection = child.position - Non_Affected_Joints[i].joint.position;
            break;
         }
         
         Vector3 combinedJointDirection = Vector3.Slerp(
            jointDirections[i], newJointDirection, Non_Affected_Joints[i].effect
         );
         
         Non_Affected_Joints[i].joint.rotation = Quaternion.FromToRotation(
            newJointDirection, combinedJointDirection
         ) * Non_Affected_Joints[i].joint.rotation;
      }
   }
   
   // The angle between dirA and dirB around axis
   public static float AngleAroundAxis (Vector3 dirA, Vector3 dirB, Vector3 axis) {
      // Project A and B onto the plane orthogonal target axis
      dirA = dirA - Vector3.Project(dirA, axis);
      dirB = dirB - Vector3.Project(dirB, axis);
      
      // Find (positive) angle between A and B
      float angle = Vector3.Angle(dirA, dirB);
      
      // Return angle multiplied with 1 or -1
      return angle * (Vector3.Dot(axis, Vector3.Cross(dirA, dirB)) < 0 ? -1 : 1);
   }
   
   
}

А вам тоже нравится в мороз выпускать изо рта тонкую струйку пара и чувствовать себя драконом?:)
Аватара пользователя
6opoDuJI0
UNIт
 
Сообщения: 85
Зарегистрирован: 06 янв 2010, 20:00

Re: HeadLookController3

Сообщение Neodrop 22 мар 2010, 20:19

Учимся использовать тег syntax

Хм, у меня ничего не перекручивает... Но гляну как-нить..
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: HeadLookController3

Сообщение WebWolf 22 мар 2010, 22:50

Neodrop писал(а):Учимся использовать тег syntax

Хм, у меня ничего не перекручивает... Но гляну как-нить..

Перекручивает с другими моделями... сайчас сделал для моделей из контры.. все отлично..
WTF? _WolfGames3D.com / Все в Tanks Heroes Вконтакте!
Аватара пользователя
WebWolf
Старожил
 
Сообщения: 532
Зарегистрирован: 19 дек 2009, 15:49
Откуда: Russian Federation
  • Сайт
  • ICQ

Re: HeadLookController3

Сообщение Neodrop 22 мар 2010, 23:48

Я с "другими" и использую. Думаю, тут прямоту рук проверять нужно, а не код. :D
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: HeadLookController3

Сообщение WebWolf 23 мар 2010, 00:44

Neodrop писал(а):Я с "другими" и использую. Думаю, тут прямоту рук проверять нужно, а не код. :D

хахах шутник))) с тем кодом не получалось :-B . А вот с этим кодом все отлично... :ymparty:
HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://newssoftware.pnz.ru/Gears.unity3d&w=800&h=600&t=true&preview=1' height='"+(600+30)+"' width='800' frameborder='0' scrolling='no'></iframe>"); </script>
Последний раз редактировалось WebWolf 23 мар 2010, 01:33, всего редактировалось 1 раз.
WTF? _WolfGames3D.com / Все в Tanks Heroes Вконтакте!
Аватара пользователя
WebWolf
Старожил
 
Сообщения: 532
Зарегистрирован: 19 дек 2009, 15:49
Откуда: Russian Federation
  • Сайт
  • ICQ

Re: HeadLookController3

Сообщение Neodrop 23 мар 2010, 01:09

Я предупреждал, что забаню? Осталось последнее предупреждение. Вот тебе пример, лабух ты, неучёный :

HTML код для вашего блога :
Код: Выделить всё
<script language='javascript' type="text/javascript"> document.write("<iframe marginheight='0' src='http://unity3d.ru/distribution/player.php?url=http://www.unity3d.ru/composition/RoboDiablo/RoboDiablo.unity3d&w=800&h=600&t=true&preview=1' height='"+(600+30)+"' width='800' frameborder='0' scrolling='no'></iframe>"); </script>


Купи себе руковыпрямитель. Ещё один глупый пост на форуме - баня на месяц. Я предупреждаю последний раз. :-?
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: HeadLookController3

Сообщение 6opoDuJI0 23 мар 2010, 08:24

действительно,не перекручивает...
хотя не только вебвульф и я наблюдали "перекручивание"
А вам тоже нравится в мороз выпускать изо рта тонкую струйку пара и чувствовать себя драконом?:)
Аватара пользователя
6opoDuJI0
UNIт
 
Сообщения: 85
Зарегистрирован: 06 янв 2010, 20:00

Re: HeadLookController3

Сообщение Neodrop 23 мар 2010, 08:41

Вопрос только настроек. Слишком большие углы заданы.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: HeadLookController3

Сообщение 6opoDuJI0 23 мар 2010, 17:32

не,вы не поняли
временами при передвижении модель крутило,трясло и лихорадило,как при экзорцизме Изображение
какбудто скрипт cursorhit прикреплённый на цель, иногда запаздывал с установкой переменной target HeadLookController'а(но это только если ставить этот геймобъект чайлдом к вашему префабу игрока,например,в шутере от третьего лица)
тут же этот скрипт цеплять к цели вообще не нужно,это может быть просто пустой геймобъект,главное установить его в переменную target
А вам тоже нравится в мороз выпускать изо рта тонкую струйку пара и чувствовать себя драконом?:)
Аватара пользователя
6opoDuJI0
UNIт
 
Сообщения: 85
Зарегистрирован: 06 янв 2010, 20:00


Вернуться в Исходники (Копилка)

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3