Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1038434 Posts in 41964 Topics- by 33589 Members - Latest Member: MatthewHayden14

September 02, 2014, 11:01:23 PM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)relative cam on arbitrary angled surfaces - take two
Pages: [1] 2
Print
Author Topic: relative cam on arbitrary angled surfaces - take two  (Read 754 times)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« on: March 14, 2013, 12:11:43 AM »

https://dl.dropbox.com/u/24530447/flash%20build/litesonicengine/LiteSonicEngine.html

I had digested difficulties and advices in the old thread, broke down things, solve some on my own and finally tossed everything to start again but focused on relevant aspect.

There is two problem:

1. relative cam
a - I should be able to make the camera turn around the local up vector of the avatar. This at any angle this up vector might be.
b - I should be able to keep the relative camera direction constant when the character move on a sphere (arbitrary surface angles) but not dependent of the character direction (local XZ plane).
c - I should be able to turn the independent character direction in the direction of the input based on local XZ plane of the camera.

2. air ground transition:
I will not get into this just yet but it's kinda related. Let's solve one thing at a time.


Now 1.a should not be a problem at all, I use a specific algorithm i just need to apply it to the camera, instead of picking the ground normal I need to pick the character up vector to align to, BRILLIANT, I thought ... except the camera stay hopelessly flat for unknown reason that drive me made (see the link above). Point b and c depend on solving a.

In short, how the hell I get the camera orbiting the main character at any angle this character is, but in relative cam control (not 3PS always behind cam)?

Wait this small unity indie game does it, how is that I can't?
http://www.youtube.com/watch?v=PE2pK3xfQk4
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #1 on: March 14, 2013, 08:15:01 PM »

Here are the reduce code:

This one if for movement, magic happen in the updateOrientation() methods, anything else is fairly conventional strafe/forward code with raycast detection. In this sample the rotation code has been deleted has i'm simply trying to get the camroot to align itself with the character up with no success at all!
Code:
using UnityEngine;
using System.Collections;

public class MovementController : MonoBehaviour
{
public float
deadZoneValue = 0.1f,
acceleration  = 50.0f;


//--------------------------------------------------------------------------------------------
void OnGUI()
{
GUILayout.Label( "transform.rotation : " + transform.rotation );
GUILayout.Label( "transform.position : " + transform.position );
}

void FixedUpdate ()
{

Ray
ground_check_ray = new Ray( gameObject.transform.position, -gameObject.transform.up );
RaycastHit
raycast_result;
Rigidbody
rigid_body = gameObject.rigidbody;

if ( Physics.Raycast( ground_check_ray, out raycast_result ) )
{
Vector3
next_position;

UpdateOrientation( gameObject.transform.forward, raycast_result.normal );
next_position = GetNextPosition( raycast_result.point );
rigid_body.MovePosition( next_position );
}
}
//--------------------------------------------------------------------------------------------


private void UpdateOrientation( Vector3 forward_vector, Vector3 ground_normal )
{
Vector3
projected_forward_to_normal_surface = forward_vector - ( Vector3.Dot( forward_vector, ground_normal ) ) * ground_normal;

transform.rotation = Quaternion.LookRotation( projected_forward_to_normal_surface, ground_normal );
}

private Vector3 GetNextPosition( Vector3 current_ground_position )
{
float
input_vertical_movement = Input.GetAxisRaw( "Vertical" ),
input_horizontal_movement = Input.GetAxisRaw( "Horizontal" );

Vector3
camera_forward = this.transform.forward,
camera_right = this.transform.right,
next_position;

next_position =
current_ground_position +
gameObject.transform.up * 0.5f;

if( Mathf.Abs( input_vertical_movement ) > deadZoneValue )
{
next_position +=
camera_forward *
acceleration *
input_vertical_movement *
Time.deltaTime;
}
if( Mathf.Abs( input_horizontal_movement ) > deadZoneValue )
{
next_position +=
camera_right *
acceleration *
input_horizontal_movement *
Time.deltaTime;
}

return next_position;
}

}


Here is the camera code, the faulty nasty beast who refuse to submit, I have try different things and result are always faulty, I'll try to redo the variation and compile playable.
Basically this code run on camera, it takes as parameter a root object where a pivot (camera hook) and a target are parented (where the camera look). The idea was to place the root object at the character position and rotate it, the camera position itself on the pivot.

Code:
using UnityEngine;
using System.Collections;

public class CameraDrive : MonoBehaviour
{
public GameObject
targetObject;

public Transform
camPivot,
camTarget,
camRoot;

float
rot = 0;
//----------------------------------------------------------------------------------------------------------
void Start()
{
this.transform.position = targetObject.transform.position;
this.transform.rotation = targetObject.transform.rotation;
}

void FixedUpdate()
{
//the pivot system
camRoot.position = targetObject.transform.position;

//input on pivot orientation
float mouse_x = Input.GetAxisRaw( "camera_analog_X" ); //
rot = rot + ( 0.1f * Time.deltaTime * mouse_x ); //
wrapAngle( rot ); //

//align camroot with target object up



camRoot.rotation.SetLookRotation(targetObject.transform.forward,targetObject.transform.up);



//this camera
this.transform.position = camPivot.position; //set the camera to the pivot
this.transform.LookAt( camTarget.position ); //
}
//----------------------------------------------------------------------------------------------------------
public float wrapAngle ( float Degree )
{
while (Degree < 0.0f)
{
Degree = Degree + 360.0f;
}
while (Degree >= 360.0f)
{
Degree = Degree - 360.0f;
}
return Degree;
}

private void UpdateOrientation( Vector3 forward_vector, Vector3 ground_normal )
{
Vector3
projected_forward_to_normal_surface = forward_vector - ( Vector3.Dot( forward_vector, ground_normal ) ) * ground_normal;

transform.rotation = Quaternion.LookRotation( projected_forward_to_normal_surface, ground_normal );
}

float GetOffsetAngle( float targetAngle, float DestAngle )
{
return ((targetAngle - DestAngle + 180)% 360)  - 180;
}
//----------------------------------------------------------------------------------------------------------
void OnDrawGizmos()
{
Gizmos.DrawCube(
camPivot.transform.position,
new Vector3(1,1,1)
);

Gizmos.DrawCube(
camTarget.transform.position,
new Vector3(1,5,1)
);

Gizmos.DrawCube(
camRoot.transform.position,
new Vector3(1,1,1)
);
}

void OnGUI()
{
GUI.Label(new Rect(0,80,1000,20*10), "targetObject.transform.up : " + targetObject.transform.up.ToString());
GUI.Label(new Rect(0,100,1000,20*10), "target euler : " + targetObject.transform.eulerAngles.y.ToString());

}
}

Now let's look at different implementation and effects of the part where it should have work:

Code:
camRoot.rotation.SetLookRotation(targetObject.transform.forward,targetObject.transform.up);

Okay fine, transform.forward/up might be local so let's do better:

Code:
camRoot.rotation.SetLookRotation(
this.transform.TransformDirection(targetObject.transform.forward),
this.transform.TransformDirection(targetObject.transform.up)
);

Still not working, let's try to go random:
Code:
camRoot.rotation.SetLookRotation(
this.transform.InverseTransformDirection(targetObject.transform.forward),
this.transform.InverseTransformDirection(targetObject.transform.up)
);

Duh, the result is just the same, let's try the secret sauce which allow perfect movement on a sphere:

      
Code:
UpdateOrientation(targetObject.transform.forward,targetObject.transform.up);

Result ... result never change ... It's totally non sense and bullshit any kind of way I slice it. I know I get data from targetObject.transform, position is out rightfully, something should happen anything, broken thing, but no, just nothing, it sit down upright and do nothing!
« Last Edit: March 14, 2013, 08:43:42 PM by Gimym TILBERT » Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #2 on: March 15, 2013, 08:25:37 PM »

I change the UpdateOrientation code and now problem a is solved
Code:
private void UpdateOrientation( Vector3 forward_vector, Vector3 ground_normal )
{
Vector3
projected_forward_to_normal_surface = forward_vector - ( Vector3.Dot( forward_vector, ground_normal ) ) * ground_normal;

camRoot.transform.rotation = Quaternion.LookRotation( projected_forward_to_normal_surface, ground_normal );
}

Turns out the mistake was a silly mistake:
I applied the orientation to transform.rotation instead of camRoot.transform.rotation since the camera hold the code but apply it to the root of the cam setup.

The reason I have the camera and a separate setup is that it allow me to free the camera for more contextual code from the character itself. The camera can now pick any target. It also allow to decouple camera reference from character reference, as the camera is free I don't need to express the character in term of camera, I express the character direction relative to the setup. The camera is not always align to the character but the setup is, therefore sharing the same reference. My previous mistake was to try to lower the number of DOF in the code, I should have increase it which is what I'm doing now.

Since the camera is now aligning correctly I had simple support for camera rotation.
Code:
void FixedUpdate()
{
//the pivot system
camRoot.position = targetObject.transform.position;

//input on pivot orientation
float mouse_x = Input.GetAxisRaw( "camera_analog_X" ); //
rot = rot + ( 0.1f * Time.deltaTime * mouse_x ); //
wrapAngle( rot ); //

//when the target object rotate, it rotate too, this should not happen


UpdateOrientation(targetObject.transform.forward,targetObject.transform.up);

camRoot.transform.RotateAround(camRoot.transform.up,rot);


//this camera
this.transform.position = camPivot.position; //set the camera to the pivot
this.transform.LookAt( camTarget.position ); //
}

Simply adding camRoot.transform.RotateAround(camRoot.transform.up,rot); after the orientation update since I was already computing the rotation according to input. Works pretty good ^^ .

here is the new build:
https://dl.dropbox.com/u/24530447/flash%20build/litesonicengine/LiteSonicEngine2.html

arrow to move/strafe, mice to rotate around the character.

Now point c should be a formality, I have to express input relative to local camroot and then compare it to actual character direction, then slowly normalize lerp the too.

Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #3 on: March 18, 2013, 08:47:45 PM »

Instead of trying to implement relative movement I have done a visualization first:

First I made this function which is trivial relative cam:
Code:
Vector3 RelativeCamDirection()
{

float
input_vertical_movement = Input.GetAxisRaw( "Vertical" ),
input_horizontal_movement = Input.GetAxisRaw( "Horizontal" );

Vector3
relative_forward = camRoot.transform.forward,
relative_right = camRoot.transform.right,

relative_direction =
( relative_forward * input_vertical_movement )
+
( relative_right * input_horizontal_movement );

return relative_direction.normalized;
}

Then I added this with a new public transform ( a huge cylinder showing where the direction point at):
Code:
//debug the relcam dir
relcamdirDebug.transform.localPosition = RelativeCamDirection()*6;

and here is the build:

https://dl.dropbox.com/u/24530447/flash%20build/litesonicengine/LiteSonicEngine3.html

And oups it's all wrong I feel stupid, it's wrong even on flat surface Huh? not sure what's wrong!
I'm stupid, I'm going to fix it asap.
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #4 on: March 22, 2013, 11:01:28 PM »

So I have a bit of burnout and even simple code was flying over my head, I took a rest and came back.
As soon as my eyes land on this, I could see what was wrong.
Code:
Vector3
relative_forward = camRoot.transform.forward,
relative_right = camRoot.transform.right,

The correct way to do it is that!

Code:
Vector3
relative_forward = Vector3.forward,
relative_right = Vector3.right,

I don't even need to check to know it works:

https://dl.dropbox.com/u/24530447/flash%20build/litesonicengine/LiteSonicEngine4.html

Okay now let's effectively put it in with motion...
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #5 on: April 05, 2013, 10:06:25 PM »

I'm still failing at the same point Sad
That is I have the correct input, I have the correct translation in the camera direction ... but whenever I attempt to slowly lerp the direction of the character in direction of the input, all I get is wild spin!
Sad

Also discovered that strafing to the right has major singularity trapping on the equator!!
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #6 on: April 05, 2013, 10:14:05 PM »

The lastest working code:

Movement code

Code:
using UnityEngine;
using System.Collections;

public class MovementController : MonoBehaviour
{
public float
deadZoneValue = 0.1f,
angle,
acceleration  = 50.0f;
public Vector3
motion ;

//--------------------------------------------------------------------------------------------
void OnGUI()
{
GUILayout.Label( "transform.rotation : " + transform.rotation );
GUILayout.Label( "transform.position : " + transform.position );
GUILayout.Label( "angle : " + angle );
}

void FixedUpdate ()
{

Ray
ground_check_ray = new Ray( gameObject.transform.position, -gameObject.transform.up );
RaycastHit
raycast_result;
Rigidbody
rigid_body = gameObject.rigidbody;

if ( Physics.Raycast( ground_check_ray, out raycast_result ) )
{
Vector3
next_position;

//UpdateOrientation( gameObject.transform.forward, raycast_result.normal );
UpdateOrientation( gameObject.transform.forward, raycast_result.normal );
next_position = GetNextPosition( raycast_result.point );
rigid_body.MovePosition( next_position );
}
}
//--------------------------------------------------------------------------------------------


private void UpdateOrientation( Vector3 forward_vector, Vector3 ground_normal )
{
Vector3
projected_forward_to_normal_surface = forward_vector - ( Vector3.Dot( forward_vector, ground_normal ) ) * ground_normal;

transform.rotation = Quaternion.LookRotation( projected_forward_to_normal_surface, ground_normal );
}

private Vector3 GetNextPosition( Vector3 current_ground_position )
{
Vector3
next_position;

// //--------------------------------------------------------------------
// angle = 0;
// Vector3 dir = this.transform.InverseTransformDirection(motion);
// angle = Vector3.Angle(Vector3.forward, dir);// * 1f * Time.fixedDeltaTime;
//
// if(angle > 0) this.transform.Rotate(0,angle,0);
// //--------------------------------------------------------------------


next_position =
current_ground_position +
gameObject.transform.up * 0.5f
+ motion
;

return next_position;
}

}


camera code

Code:
using UnityEngine;
using System.Collections;

public class CameraDrive : MonoBehaviour
{
public GameObject
targetObject;

public Transform
camPivot,
camTarget,
camRoot,

relcamdirDebug;

float
rot = 0;
//----------------------------------------------------------------------------------------------------------
void Start()
{
this.transform.position = targetObject.transform.position;
this.transform.rotation = targetObject.transform.rotation;
}

void FixedUpdate()
{
//the pivot system
camRoot.position = targetObject.transform.position;

//input on pivot orientation
rot = 0;
float mouse_x = Input.GetAxisRaw( "camera_analog_X" ); //
rot = rot + ( 0.1f * Time.deltaTime * mouse_x ); //
wrapAngle( rot ); //

//when the target object rotate, it rotate too, this should not happen


UpdateOrientation(this.transform.forward,targetObject.transform.up);

camRoot.transform.RotateAround(camRoot.transform.up,rot);

//debug the relcam dir
RelativeCamDirection()
;

//this camera
this.transform.position = camPivot.position; //set the camera to the pivot
this.transform.LookAt( camTarget.position ); //
}
//----------------------------------------------------------------------------------------------------------
public float wrapAngle ( float Degree )
{
while (Degree < 0.0f)
{
Degree = Degree + 360.0f;
}
while (Degree >= 360.0f)
{
Degree = Degree - 360.0f;
}
return Degree;
}

private void UpdateOrientation( Vector3 forward_vector, Vector3 ground_normal )
{
Vector3
projected_forward_to_normal_surface = forward_vector - ( Vector3.Dot( forward_vector, ground_normal ) ) * ground_normal;

camRoot.transform.rotation = Quaternion.LookRotation( projected_forward_to_normal_surface, ground_normal );
}

float GetOffsetAngle( float targetAngle, float DestAngle )
{
return ((targetAngle - DestAngle + 180)% 360)  - 180;
}
//----------------------------------------------------------------------------------------------------------
void OnDrawGizmos()
{
Gizmos.DrawCube(
camPivot.transform.position,
new Vector3(1,1,1)
);

Gizmos.DrawCube(
camTarget.transform.position,
new Vector3(1,5,1)
);

Gizmos.DrawCube(
camRoot.transform.position,
new Vector3(1,1,1)
);
}

void OnGUI()
{
GUI.Label(new Rect(0,80,1000,20*10), "targetObject.transform.up : " + targetObject.transform.up.ToString());
GUI.Label(new Rect(0,100,1000,20*10), "target euler : " + targetObject.transform.eulerAngles.y.ToString());
GUI.Label(new Rect(0,100,1000,20*10), "rot : " + rot.ToString());

}
//----------------------------------------------------------------------------------------------------------
void RelativeCamDirection()
{

float
input_vertical_movement = Input.GetAxisRaw( "Vertical" ),
input_horizontal_movement = Input.GetAxisRaw( "Horizontal" );

Vector3
relative_forward = Vector3.forward,
relative_right = Vector3.right,

relative_direction =
( relative_forward * input_vertical_movement )
+
( relative_right * input_horizontal_movement )
;

MovementController MC = targetObject.GetComponent<MovementController>();

MC.motion = relative_direction.normalized * MC.acceleration * Time.fixedDeltaTime;

MC.motion = this.transform.TransformDirection( MC.motion );

//MC.transform.Rotate(Vector3.up, input_horizontal_movement * 10f * Time.fixedDeltaTime);
}
}
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #7 on: April 05, 2013, 10:33:33 PM »

Latest demo
https://dl.dropbox.com/u/24530447/flash%20build/litesonicengine/LiteSonicEngine5.html
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #8 on: April 06, 2013, 01:36:29 PM »


I made a new demo, and it's totally broken ...
https://dl.dropbox.com/u/24530447/flash%20build/litesonicengine/LiteSonicEngine5a.html

I have toss the problem at internet for 3 years, and it is still scratching is head.
So I asked the only person I knew who had solve the problem:

Quote from: Sophie Houlden
What's "the move"? is there some secret trick I don't know about? o__o
ah right, how I *coded* it, gotcha! well... it's been a while but I'll try to explain my hazy memory of the system!
raycast down to find the floor, whatever normal that ray hit then has, is "up"
convert (vector that is input*cam directions) relative to the plane determind by "up", move sarah along that plane...
then raycast again to find new 'up'. I realise the middle step is more or less voodoo, but that's where my memoryis hazy
IIRC things I tried were unity's own Plane class or some such, quite handy, and also making empty reference gameobjects
there was also some degree of rotating stuff in another thing's local space so that 'forward' and 'left' never jumped 180
otherwise you could get sarah to go jittery the moment you cross odd angles
ya, even with the right approach if you use the transformpoint when you want inverse or have a bad lookat it all breaks
can't remember how I used it, but I think it solved some problems http://docs.unity3d.com/Documentation/ScriptReference/Plane.html …
...though it might have been for a different game entirely... sorry if that's the case, hazy memory really is hazy ^__^;

Now I need to parse the clue ...
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
moi
Level 10
*****


DILF SANTA


View Profile WWW
« Reply #9 on: April 06, 2013, 01:51:38 PM »

send me the unity source file, I'll fix it for you
Logged

subsystems   subsystems   subsystems
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #10 on: April 06, 2013, 02:05:53 PM »

The goal was to make it open source anyway once solved


Zipped project
https://dl.dropbox.com/u/24530447/sonic%20engine/lite%20sonic%20engine.rar

Unitypackage
https://dl.dropbox.com/u/24530447/LiteSonicEngine5a.unitypackage
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
moi
Level 10
*****


DILF SANTA


View Profile WWW
« Reply #11 on: April 06, 2013, 02:17:01 PM »

I'll take a look
Logged

subsystems   subsystems   subsystems
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #12 on: April 06, 2013, 03:41:58 PM »

Thanks
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #13 on: April 07, 2013, 05:22:50 PM »

Okay I got a little lost on the way.

First the original code in the op just works. So I have a character correctly moving on a sphere (arbitrary slopes angles).

The problem is that I try to have a vector from the camera "setup" (which share the alignment (same plane) of the character, except for the local Y rot) and then align the character to that vector ON THE SAME PLANE! Which is essentially a local problem and strictly 2D!

HOW DOES THE HELL THIS GO WRONG  Cry  WTF Huh?  Sad Shocked Angry  My Word!  Apoplectic Outraged Mock Anger Screamy Concerned Facepalm the jury is still out and confused
Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Gimym JIMBERT
Level 10
*****


NOTGAMER ludophile


View Profile Email
« Reply #14 on: April 07, 2013, 07:39:36 PM »

Movement

Code:
using UnityEngine;
using System.Collections;

public class MovementController : MonoBehaviour
{
public float
deadZoneValue = 0.1f,
angle,
acceleration  = 50.0f;
public Vector3
motion ;

//--------------------------------------------------------------------------------------------
void OnGUI()
{
GUILayout.Label( "transform.rotation : " + transform.rotation );
GUILayout.Label( "transform.position : " + transform.position );
GUILayout.Label( "angle : " + angle );
}

void FixedUpdate ()
{

Ray
ground_check_ray = new Ray( gameObject.transform.position, -gameObject.transform.up );
RaycastHit
raycast_result;
Rigidbody
rigid_body = gameObject.rigidbody;

if ( Physics.Raycast( ground_check_ray, out raycast_result ) )
{
Vector3
next_position;

//UpdateOrientation( gameObject.transform.forward, raycast_result.normal );
UpdateOrientation( gameObject.transform.forward, raycast_result.normal );
next_position = GetNextPosition( raycast_result.point );
rigid_body.MovePosition( next_position );
}
}
//--------------------------------------------------------------------------------------------


private void UpdateOrientation( Vector3 forward_vector, Vector3 ground_normal )
{
Vector3
projected_forward_to_normal_surface = forward_vector - ( Vector3.Dot( forward_vector, ground_normal ) ) * ground_normal;

transform.rotation = Quaternion.LookRotation( projected_forward_to_normal_surface, ground_normal );
}

private Vector3 GetNextPosition( Vector3 current_ground_position )
{
Vector3
next_position;

// //--------------------------------------------------------------------
// angle = 0;
// Vector3 dir = this.transform.InverseTransformDirection(motion);
// angle = Vector3.Angle(Vector3.forward, dir);// * 1f * Time.fixedDeltaTime;
//
// if(angle > 0) this.transform.Rotate(0,angle,0);
// //--------------------------------------------------------------------


next_position =
current_ground_position +
gameObject.transform.up * 0.5f
+ motion
;

return next_position;
}

}

Camera

Code:
using UnityEngine;
using System.Collections;

public class CameraDrive : MonoBehaviour
{
public GameObject
targetObject;

public Transform
camPivot,
camTarget,
camRoot,

relcamdirDebug;

float
rot = 0;
//----------------------------------------------------------------------------------------------------------
void Start()
{
this.transform.position = targetObject.transform.position;
this.transform.rotation = targetObject.transform.rotation;
}

void FixedUpdate()
{
//the pivot system
camRoot.position = targetObject.transform.position;

//input on pivot orientation
rot = 0;
float mouse_x = Input.GetAxisRaw( "camera_analog_X" ); //
rot = rot + ( 0.1f * Time.deltaTime * mouse_x ); //
wrapAngle( rot ); //

//when the target object rotate, it rotate too, this should not happen


UpdateOrientation(this.transform.forward,targetObject.transform.up);

camRoot.transform.RotateAround(camRoot.transform.up,rot);

//debug the relcam dir
RelativeCamDirection()
;

//this camera
this.transform.position = camPivot.position; //set the camera to the pivot
this.transform.LookAt( camTarget.position ); //
}
//----------------------------------------------------------------------------------------------------------
public float wrapAngle ( float Degree )
{
while (Degree < 0.0f)
{
Degree = Degree + 360.0f;
}
while (Degree >= 360.0f)
{
Degree = Degree - 360.0f;
}
return Degree;
}

private void UpdateOrientation( Vector3 forward_vector, Vector3 ground_normal )
{
Vector3
projected_forward_to_normal_surface = forward_vector - ( Vector3.Dot( forward_vector, ground_normal ) ) * ground_normal;

camRoot.transform.rotation = Quaternion.LookRotation( projected_forward_to_normal_surface, ground_normal );
}

float GetOffsetAngle( float targetAngle, float DestAngle )
{
return ((targetAngle - DestAngle + 180)% 360)  - 180;
}
//----------------------------------------------------------------------------------------------------------
void OnDrawGizmos()
{
Gizmos.DrawCube(
camPivot.transform.position,
new Vector3(1,1,1)
);

Gizmos.DrawCube(
camTarget.transform.position,
new Vector3(1,5,1)
);

Gizmos.DrawCube(
camRoot.transform.position,
new Vector3(1,1,1)
);
}

void OnGUI()
{
GUI.Label(new Rect(0,80,1000,20*10), "targetObject.transform.up : " + targetObject.transform.up.ToString());
GUI.Label(new Rect(0,100,1000,20*10), "target euler : " + targetObject.transform.eulerAngles.y.ToString());
GUI.Label(new Rect(0,100,1000,20*10), "rot : " + rot.ToString());

}
//----------------------------------------------------------------------------------------------------------
void RelativeCamDirection()
{

float
input_vertical_movement = Input.GetAxisRaw( "Vertical" ),
input_horizontal_movement = Input.GetAxisRaw( "Horizontal" );

Vector3
relative_forward = Vector3.forward,
relative_right = Vector3.right,

relative_direction =
( relative_forward * input_vertical_movement )
+
( relative_right * input_horizontal_movement )
;

MovementController MC = targetObject.GetComponent<MovementController>();

MC.motion = relative_direction.normalized * MC.acceleration * Time.fixedDeltaTime;

MC.motion = this.transform.TransformDirection( MC.motion );

//MC.transform.Rotate(Vector3.up, input_horizontal_movement * 10f * Time.fixedDeltaTime);
if (MC.motion.sqrMagnitude > 0)
{
Quaternion target = Quaternion.LookRotation( relative_direction, MC.transform.up );
MC.transform.rotation = Quaternion.Slerp(MC.transform.rotation, target, 0.5f);
}
}
}

I didn't provide the modified code for the 5a version, only the camera was changed, 2 lines of code added
« Last Edit: April 07, 2013, 08:01:32 PM by Gimym TILBERT » Logged


ILLOGICAL, random guy on internet, do not trust (lelebĉcülo dum borobürükiss)
Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic