Caméra à la World of Warcraft

Pour la gestion de la caméra dans une vue à la 3ème personne, Unity est fournit avec un script sympa mais limité nommé SmoothFollow. Le problème est que la caméra ne se replace pas si un obstacle est situé entre le personnage et elle.

En cherchant un peu sur le forum officiel, j’ai trouvé une classe créée par omoymenya et qui permet d’avoir une caméra à la WoW avec gestion de la souris, idéale pour tout MMO ou jeu d’aventure.

Pour s’en servir, créez un script C# nommé WowCamera.cs avec le code ci-dessous, placez le script sur la caméra et dans la variable Target, placez votre personnage en drag and drop.

?Download download.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
using UnityEngine;
using System.Collections;
 
 
 
public class WowCamera : MonoBehaviour
{
    public Transform target;
 
    public float targetHeight = 1.7f;
    public float distance = 5.0f;
    public float offsetFromWall = 0.1f;
 
    public float maxDistance = 20;
    public float minDistance = .6f;
 
    public float xSpeed = 200.0f;
    public float ySpeed = 200.0f;
   public float targetSpeed = 5.0f;
 
 
    public int yMinLimit = -80;
    public int yMaxLimit = 80;
 
    public int zoomRate = 40;
 
    public float rotationDampening = 3.0f;
    public float zoomDampening = 5.0f;
 
    public LayerMask collisionLayers = -1;
 
    private float xDeg = 0.0f;
    private float yDeg = 0.0f;
    private float currentDistance;
    private float desiredDistance;
    private float correctedDistance;
 
    void Start ()
    {
        Vector3 angles = transform.eulerAngles;
        xDeg = angles.x;
        yDeg = angles.y;
 
        currentDistance = distance;
        desiredDistance = distance;
        correctedDistance = distance;
 
        // Make the rigid body not change rotation
        if (rigidbody)
            rigidbody.freezeRotation = true;
    }
 
 
   void Update()
   {
 
      //Move the Player with left & right button press together
      if(Input.GetMouseButton(1)&&Input.GetMouseButton(0))
      {
      float targetRotationAngle = target.eulerAngles.y;
      float currentRotationAngle = transform.eulerAngles.y;
      xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);             
      target.transform.Rotate(0,Input.GetAxis ("Mouse X") * xSpeed  * 0.02f,0);
      xDeg += Input.GetAxis ("Mouse X") * targetSpeed * 0.02f;
      target.transform.Translate(Vector3.forward * targetSpeed * Time.deltaTime);
      }
   }
 
    /**
     * Camera logic on LateUpdate to only update after all character movement logic has been handled.
     */
    void LateUpdate ()
    {
       Vector3 vTargetOffset;
 
       // Don't do anything if target is not defined
        if (!target)
            return;
 
        // If either mouse buttons are down, let the mouse govern camera position
        if (Input.GetMouseButton(0))
        {
            xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
            yDeg -= Input.GetAxis ("Mouse Y") * ySpeed * 0.02f;
        }
      //Reset the camera angle and Rotate the Target Around the World!
      else if (Input.GetMouseButton(1))
      {
      float targetRotationAngle = target.eulerAngles.y;
      float currentRotationAngle = transform.eulerAngles.y;
      xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);    
      target.transform.Rotate(0,Input.GetAxis ("Mouse X") * xSpeed * 0.02f,0);
      xDeg += Input.GetAxis ("Mouse X") * xSpeed * 0.02f;
      }
 
 
        // otherwise, ease behind the target if any of the directional keys are pressed
        else if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
        {
            float targetRotationAngle = target.eulerAngles.y;
            float currentRotationAngle = transform.eulerAngles.y;
            xDeg = Mathf.LerpAngle (currentRotationAngle, targetRotationAngle, rotationDampening * Time.deltaTime);
        }
 
        yDeg = ClampAngle (yDeg, yMinLimit, yMaxLimit);
 
 
        // set camera rotation
        Quaternion rotation = Quaternion.Euler (yDeg, xDeg, 0);
 
        // calculate the desired distance
        desiredDistance -= Input.GetAxis ("Mouse ScrollWheel") * Time.deltaTime * zoomRate * Mathf.Abs (desiredDistance);
        desiredDistance = Mathf.Clamp (desiredDistance, minDistance, maxDistance);
        correctedDistance = desiredDistance;
 
        // calculate desired camera position
        vTargetOffset = new Vector3 (0, -targetHeight, 0);
        Vector3 position = target.position - (rotation * Vector3.forward * desiredDistance + vTargetOffset);
 
        // check for collision using the true target's desired registration point as set by user using height
        RaycastHit collisionHit;
        Vector3 trueTargetPosition = new Vector3 (target.position.x, target.position.y + targetHeight, target.position.z);
 
        // if there was a collision, correct the camera position and calculate the corrected distance
        bool isCorrected = false;
        if (Physics.Linecast (trueTargetPosition, position, out collisionHit, collisionLayers.value))
        {
            // calculate the distance from the original estimated position to the collision location,
            // subtracting out a safety "offset" distance from the object we hit.  The offset will help
            // keep the camera from being right on top of the surface we hit, which usually shows up as
            // the surface geometry getting partially clipped by the camera's front clipping plane.
            correctedDistance = Vector3.Distance (trueTargetPosition, collisionHit.point) - offsetFromWall;
            isCorrected = true;
        }
 
        // For smoothing, lerp distance only if either distance wasn't corrected, or correctedDistance is more than currentDistance
        currentDistance = !isCorrected || correctedDistance > currentDistance ? Mathf.Lerp (currentDistance, correctedDistance, Time.deltaTime * zoomDampening) : correctedDistance;
 
      // keep within legal limits
        currentDistance = Mathf.Clamp (currentDistance, minDistance, maxDistance);
 
        // recalculate position based on the new currentDistance
        position = target.position - (rotation * Vector3.forward * currentDistance + vTargetOffset);
 
        transform.rotation = rotation;
        transform.position = position;
    }
 
    private static float ClampAngle (float angle, float min, float max)
    {
        if (angle < -360)
            angle += 360;
        if (angle > 360)
            angle -= 360;
        return Mathf.Clamp (angle, min, max);
    }
}

Script de gestion de XML dans Unity

En natif, Unity ne gère pas le xml comme le ferai Flash avec des méthodes déjà créées, mais comme en code tout est possible, voici une solution développée sur le site pennymo.com.

Evidemment, quand on connais le C# par coeur, c’est facile de trouver la solution hein ? Pas de quoi pavoiser 🙂

Toutes les explications sont fournis sur le site et le code complet est ici, à vous les joies du XML.

Sortie de Unity Iphone 1.5.1

Mise à jour pour Unity Iphone avec cette nouvelle version 1.5.1 qui est sortie hier. Dans la liste des nouveautés, l’équipe de Unity a surtout enlevé un bug qui permetter d’accéder à des données protégées par l’iphone. Cela fait surtout suite au rejet d’une grandes quantités d’applications de l’applestore mais les développeurs ont été très réactifs pour corriger la faille.

L’autre nouveauté est la possibilité d’installer la trial de Unity Iphone sans être obligé de demander une clé de 30 jours au support technique. Je rappelle que Unity Iphone ne marche que sur Mac avec un os 10.5.4.

Cityengine, un générateur de ville

Cityengine est un générateur de ville assez génial. Vous pouvez créer toute sorte de bâtiment en 3D en modifiant une quantité de paramètres assez impressionnante (taille, fenêtres, volume, style).

N’importe qui peut avec cet outil créer une ville imaginaire, qu’elle soit moderne ou antique. Dans la vidéo suivante, les créateurs du soft vous montre comment coupler leur logiciel avec Unity afin de gagner en production.

Cityengine n’est évidemment pas gratuit et existe en 2 version, une version simple à 3450$ et une version proà 4950$. Je trouve que c’est quand même un peu cher mais bon.

Google earth et Unity

Voici un tutoriel en anglais assez original qui va vous expliquer comment intégrer las cartes de Google earth dans une appli Unity.

L’auteur a recréer l’île de KAUAIsur son site, celà semble assez technique à mettre en place mais ça marche. J’avais vu quelqu’un faire la même chose avec flash mais c’était en 2D. Vous trouverez d’autres tutos sur le site www.3dnemo.com.

Le tutoriel

OMG PIRATES ! L’après ZombieVille

L’équipe Mikamobile est à l’origine d’un jeu Iphone créé avec Unity et nommé ZombieVille. Véritable succès, il fut un des jeux qui attirèrent l’attention des développeurs pour Unity 3D avec le paradoxe qu’il s’agit d’un jeu en rendu 2D.

A la vue du style cartoon on ne se douterait pas qu’en fait le jeu est entièrement créé avec des modèles 3D et utilise les outils classiques comme le CharacterController et les scripts d’animations.

L’équipe revient donc avec un nouveau jeu nommé OMG PIRATES ! est qui est une peu plus dans le style de Castle Crushers. Regardez donc le trailer suivant, ça fait envie.

Il ne m’en fallait pas plus pour taner un des créateurs dont le pseudo est PirateNinjaAlliance sur le forum officiel et j’ai pu glaner quelques informations techniques quand à leur manière de travailler qui est simple et géniale à la fois.

En fait, pour les personnages, il sépare les portions de corps dans des images différentes (tête, bras…) et ensuite dans Maya, il créé des planars (en fait des mesh rectangulaires à 2 polygones) et ils appliquent les images de corps aux mesh. Ensuite, il anime le tout dans Maya. Celà ressemble à une animation flash mais dans un logiciel 3D. Ensuite, comme certains mouvements sont contraints par le dessin, il créé différentes position suivant les actions du personnage (si il est de dos, si il fait un coup spécial). Ensuite comme vous le voyez sur l’image ci-dessous la caméra est placé à 45 degrés et très loin avec un grand angle, ce qui permet une caméra presque orthographique mais qui conserve la parallaxe des éléments de décors placés sur différentes profondeur. Quand au décor du fond, il est penché dans l’axe de la caméra. Et le tour est joué.

art15a

Script de morphing

Voici un script qui réalise le morphing entre modèle 3D qui ont une base neutre commune mais auxquels vous aurez créé 2 états différents. Cette expérimentation a été réalisé avec un export du modèle depuis Blender par Foolish Frost. Sur son site, vous pourrez voir la démo appliquée à un monstre tentaculaire et à un visage de femme.

Si vous voulez expérimenter vous même ou jouer à modifier le script, téléchargez le package ici.

Pack de 16 Lensflare

Dans unity vous pouvez placer divers type de lumières d’ambiance mais il faut savoir que vous pouvez ajouter à votre lumière un effet de Lensflare pour donner un rendu étoile, soleil ou autre éclat de lumière.

Voici donc sur le site officiel un pack de 16 Lensflare et je peux vous dire qu’ils sont impressionnants de réalisme. Pour vous en servir, téléchargez le package, importez le et placez en drag and drop le Lensflare adéquat sur votre lumière.

Page 48 sur 50« Première page1020304647484950