Unity RotateAround Clamp Dead Zone Issue - unity3d

For the past 3 days, I have tried numerous methods and read dozens of questions on forums in order to achieve the desired effect of rotating a camera on the Y axis using mouse rotations, and clamping the rotation within a certain range. The amount of rotation is dependent on how close the mouse is to the edge of the screen.
I was unable to find a solution, but I was able to learn enough to have my own honest attempt at it, and I came quite close. The prominent issue I faced was being able to properly clamp the RotateAround() inside of the desired range. This is because of eulerAngles being 0 - 360, and having the min and max of the clamp transition to the other side of the spectrum.
By clamping the rotation degrees before calling RotateAround, I was able to get the clamping to work, though I had to use Booleans to get them to work properly.
My current issue is that when the initial Y rotation(anchor) is slightly below 360, the camera fails to clamp on the left and will clamp back around to the right side of the range.
In all other situations, the clamping works just fine:
Initial Y rotation slightly above 0
Not within the dead zone
While debugging, I find that this is because rightOverFlag is true. When I set this bool to true manually in situations clamping normally works fine, the clamping will no longer work on the left.
I can't seem to find how this bool being true causes something like this to happen, so I am hoping some fresh eyes and seasoned advice can help me learn from this. Thank you.
public gameState gameState;
public openCams openCams;
private GameObject GameStateManager;
[SerializeField]
private GameObject Player;
[SerializeField]
private Camera cam;
// Rotation Variables
private Quaternion initialRotation;
private float initialYRotation = 0f;
[SerializeField]
private float angleRange;
private float anchorY = 0f;
public bool leftOverFlag = false;
public bool rightOverFlag = false;
void Start()
{
cam = Camera.main;
Cursor.lockState = CursorLockMode.None;
}
public void OrientControls()
{
initialRotation = Player.transform.rotation;
initialYRotation = Player.transform.eulerAngles.y;
anchorY = initialYRotation;
if (anchorY > 360)
{
anchorY -= 360;
}
rightOverFlag = false;
leftOverFlag = false;
if ((anchorY + angleRange) > 360)
{
rightOverFlag = true;
}
else if ((anchorY - angleRange) <= 0)
{
leftOverFlag = true;
}
}
void Update()
{
if (openCams.GetMonitorState() == false)
{
mousePos = Input.mousePosition;
float rotateDegrees = 0f;
//Debug.Log(Player.transform.eulerAngles.y);
// THERE IS CODE HERE THAT INCREASES ROTATE DEGREES BASED ON MOUSE POSITION. I removed it for the sake of readability, because it was quite long and unrelated to my issue.
float angleFromInitial = Quaternion.Angle(initialRotation, Player.transform.rotation);
float currentPlayerYRot = Player.transform.eulerAngles.y;
if (currentPlayerYRot > 360)
{
currentPlayerYRot -= 360;
}
bool currentRightOverageFlag = false;
bool currentLeftOverageFlag = false;
if (rightOverFlag)
{
if ((currentPlayerYRot) < (anchorY - (angleRange - 5))) //
{
currentRightOverageFlag = true;
}
}
if (leftOverFlag)
{
if ((currentPlayerYRot) > (anchorY + (angleRange + 5)))
{
currentLeftOverageFlag = true;
}
}
// !!! - For some reason, when rightOverFlag is enabled, the clamp does not work on the left side. In all other situations, the clamp works perfectly.- !!!
if (!currentLeftOverageFlag && !currentRightOverageFlag)
{
if (currentPlayerYRot < anchorY) // Regular
{
angleFromInitial *= -1;
}
}
else if (currentLeftOverageFlag && !currentRightOverageFlag)
{
if (currentPlayerYRot > anchorY) // If over the left line
{
angleFromInitial *= -1;
}
}
else if (!currentLeftOverageFlag && currentRightOverageFlag)
{
if (currentPlayerYRot > anchorY) // If over the right line
{
angleFromInitial *= -1;
}
}
else
{
Debug.Log("staticPersonController: ERROR => Cannot have current left and right overage flags enabled at the same time.");
}
currentLeftOverageFlag = false;
currentRightOverageFlag = false;
float newAngle = Mathf.Clamp(angleFromInitial + rotateDegrees, -angleRange, angleRange);
rotateDegrees = newAngle - angleFromInitial;
Player.transform.RotateAround(Player.transform.position, Vector3.up, rotateDegrees);
}
}
}

Assume you have these two variables set.
// This is the initial value of the player's Y rotation. Set only once.
float initialRotY = Player.transform.eulerAngles.y;
// This is the offset of the player's Y rotation based on the cursor position
// e.g. -90 when the cursor is on the left edge and 90 on the right
float mouseBasedRotY;
In the Update method, just do this.
Player.transform.rotation = Quaternion.Euler(0f, initialRotY + mouseBasedRotY, 0f);
You don't have to clamp the value, because the degree is always limited in [initialRotY-90, initialRotY+90]

Related

Draging camera to a limit (x, y axis) - UNITY

i did a tutorial about doing a camera drag on a 2D or 3D worldmap.
The code is working. Looks like the following:
void Update_CameraDrag ()
{
if( Input.GetMouseButtonUp(0) )
{
Debug.Log("Cancelling camera drag.");
CancelUpdateFunc();
return;
}
// Right now, all we need are camera controls
Vector3 hitPos = MouseToGroundPlane(Input.mousePosition);
//float maxWidth = 10;
//if (hitPos.x > maxWidth)
//{
// hitPos.x = maxWidth;
//}
Vector3 diff = lastMouseGroundPlanePosition - hitPos;
Debug.Log(diff.x+ Space.World);
Camera.main.transform.Translate (diff, Space.World);
lastMouseGroundPlanePosition = hitPos = MouseToGroundPlane(Input.mousePosition);
}
Now my problem is, that you can drag unlimiited into any directions.
I would rather like to difine something like borders on the x and y axis.
Basically maximum values for the camera. If the camera would surpass these values, their position value would be set to the given maximum value.
Unfortunately, i am not sure how it works, especially, since the tutorial set everything into relation to Space.World - and i am not even sure what that is. I mean i understand that "diff" is the change between the current position and the new positon in relation to Space.World and then the camera gets moved accordingly. I would just like to define a max value which the camera can not surpass. Any ideas how to do that. I am unfortunately still learning - so kinda hard for me and i was hoping for help.
If you were to record the X and Y position of the camera as it goes in a variable and use the MathF function. I.e
if you have a map that is 100(x)x150(y)units you could use
xPositionOfCamera = Mathf.Clamp(xPositionOfCamera, -50, 50);
yPositionOfCamera = Mathf.Clamp(YPositionOfCamera, -75, 75);
I'm not 100% sure if that's what you want it to do, but it's how I would limit it.
I write a simple and reliable script for my game to handle camera drag and swipe for any camera aspect ratio. Everyone can use this code easily :) Just adjust the xBoundWorld and yBoundWorld values
using UnityEngine;
public class CameraDragController : MonoBehaviour
{
[SerializeField] private Vector2 xBoundWorld;
[SerializeField] private Vector2 yBoundWorld;
[SerializeField] public bool HorizentalDrag = true;
[SerializeField] public bool VerticalDrag = true;
[SerializeField] public float speedFactor = 10;
private float leftLimit;
private float rightLimit;
private float topLimit;
private float downLimit;
public bool allowDrag = true;
private void Start()
{
CalculateLimitsBasedOnAspectRatio();
}
public void UpdateBounds(Vector2 xBoundNew, Vector2 yBoundNew)
{
xBoundWorld = xBoundNew;
yBoundWorld = yBoundNew;
CalculateLimitsBasedOnAspectRatio();
}
private void CalculateLimitsBasedOnAspectRatio()
{
leftLimit = xBoundWorld.x - Camera.main.ViewportToWorldPoint(new Vector3(0, 0, 0)).x;
rightLimit = xBoundWorld.y - Camera.main.ViewportToWorldPoint(new Vector3(1, 0, 0)).x;
downLimit = yBoundWorld.x - Camera.main.ViewportToWorldPoint(new Vector3(0, 0, 0)).y;
topLimit = yBoundWorld.y - Camera.main.ViewportToWorldPoint(new Vector3(0, 1, 0)).y;
}
Vector3 lastPosView; // we use viewport because we don't want devices pixel density affect our swipe speed
private void LateUpdate()
{
if (allowDrag)
{
if (Input.GetMouseButtonDown(0))
{
lastPosView = Camera.main.ScreenToViewportPoint(Input.mousePosition);
}
else if (Input.GetMouseButton(0))
{
var newPosView = Camera.main.ScreenToViewportPoint(Input.mousePosition);
var cameraMovment = (lastPosView - newPosView) * speedFactor;
lastPosView = newPosView;
cameraMovment = Limit2Bound(cameraMovment);
if (HorizentalDrag)
Camera.main.transform.Translate(new Vector3(cameraMovment.x, 0, 0));
if (VerticalDrag)
Camera.main.transform.Translate(new Vector3(0, cameraMovment.y, 0));
}
}
}
private Vector3 Limit2Bound(Vector3 distanceView)
{
if (distanceView.x < 0) // Check left limit
{
if (Camera.main.transform.position.x + distanceView.x < leftLimit)
{
distanceView.x = leftLimit - Camera.main.transform.position.x;
}
}
else // Check right limit
{
if (Camera.main.transform.position.x + distanceView.x > rightLimit)
{
distanceView.x = rightLimit - Camera.main.transform.position.x;
}
}
if (distanceView.y < 0) // Check down limit
{
if (Camera.main.transform.position.y + distanceView.y < downLimit)
{
distanceView.y = downLimit - Camera.main.transform.position.y;
}
}
else // Check top limit
{
if (Camera.main.transform.position.y + distanceView.y > topLimit)
{
distanceView.y = topLimit - Camera.main.transform.position.y;
}
}
return distanceView;
}
}

unity update skipping calculation in a frame

I'm Instantiating tiles as a path, on every four instantiating's tiles, they should start instantiating towards right, after four instantiating's, they go straight again.
to check this logic I, made a variable spawnOffset and incrementing +1 each frame.
if spawnOffset % 4 == 0 change direction
but, i'm not getting a change in direction in regular intervals, when i debug, the frame skips and so is the logic
public GameObject go;
public Transform Playertransform;
public Vector3 tileSpawnOffset = Vector3.zero;
private Vector3 direction = Vector3.forward;
public int SpawnOffset = -3;
private bool turnRight = false;
void Update()
{
SpawnPath();
ChangeDirection();
}
void SpawnPath()
{
if (Playertransform.position.z > SpawnOffset)
{
tileSpawnOffset += direction;
Instantiate(go, this.transform.position + tileSpawnOffset, this.transform.rotation, this.transform);
SpawnOffset++;
}
}
void ChangeDirection()
{
if (SpawnOffset % 4 == 0)
{
turnRight = !turnRight;
}
direction = turnRight == true ? Vector3.right : Vector3.forward;
}
and but when i tried with time instead
float time = 0f;
void ChangeDirection()
{
time += Time.deltaTime;
if (time > 1)
{
turnRight = !turnRight;
time = 0;
}
direction = turnRight == true ? Vector3.right : Vector3.forward;
}
it works perfectly fine. so, how could i fix it. I, don't want use time, i want to change direction exactly after 4 tiles spawned
Since your always calling both SpawnPath(); ChangeDirection(); everyframe if (Playertransform.position.z > SpawnOffset) is ever false twice in a row your turnright bool gets flipped regardless every frame your on a multiple of 4. You don't need to call ChangeDirection if you didn't spawn a new tile. if you just remove that call from update and add it at right after your increment SpawnOffset its probably going to fixe it.

Unity 2D Rigidbody.velocity and transform.position causes random 'ghost' frame

I am creating a 2D platform / adventure game that uses flip screen to manage changing rooms.
My character moves using RigidBody.velocity, this works as I need it to, when my character reaches one of the screen's left or right extremes I use transform.position to move (effectively teleporting) the character to the other side of the screen, I then change the room. This gives the effect of moving to the next room along.
My flip screen code works fine, the changing room effect works without a problem, in fact almost everything works just as I like it, except that I get 1 frame where the character appears at a random point in between where the character moved from and where he moved to.
For example, my room is 16 tiles across, if my character moves left and passes x position '0' (the very left of the screen) I make a transform.position to x position 16 (keeping the y position constant) and then change rooms. I have logged the movement and what happens is (pseudo code)..
x < 0 (the change room code is run)
translate.position to x=16 (the far right)
x = 16 (this is correct)
The room changes
x = some float somewhere between 0 and 16 (this is NOT correct)
x = 16 (back to the correct position again)
This is my player code:
using UnityEngine;
using System.Collections;
public class MKManager : MonoBehaviour {
public float maxSpeed = 0.10f;
bool isFacingRight = false;
Rigidbody2D myBody;
bool grounded = true;
public static int liftdirection = 0;
void Start (){
myBody = GetComponent<Rigidbody2D> ();
}
void Update () {
checkRoomBounds ();
}
void FixedUpdate(){
float h = Input.GetAxisRaw ("Horizontal");
if (grounded) {
myBody.velocity = new Vector2 (h * maxSpeed, myBody.velocity.y);
if (h < 0) { //Moving Left
if (isFacingRight) {
FlipAnimation ();
}
} else if (h > 0) { //Moving Right
if (!isFacingRight) {
FlipAnimation ();
}
}
}
}
void checkRoomBounds(){
if (transform.position.x < 0) {
transform.position = new Vector3 (16.0f, transform.position.y, 0.0f);
GameManager.instance.moveRoom (-1);
} else if (transform.position.x > 16) {
transform.position = new Vector3 (0.0f, transform.position.y, 0.0f);
GameManager.instance.moveRoom (1);
}
}
void FlipAnimation(){
isFacingRight = !isFacingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
I have tried calling checkRoomBounds() in update, fixed update and lateupdate, all give the same result. If I do not call the moveRoom() function the same happens but the room is not changed, but the moveRoom() code is...
public void moveRoom(int direction){
if (room == 0) {
room = (10*currentFloor) + 1;
} else {
room += direction;
if (room == -1) {
room = 68;
} else if (room == 69) {
room = 0;
} else if (room % 10 == 9 || room % 10 == 0) {
//room += (direction * 2);
room = 0;
}
}
boardScript.SetupScene (room);
}
I've run out of ideas and don't know where I'm going wrong. Any help would be much appreciated.
Many thanks in advance

Unity3d - Moving camera literally cuts FPS in half?

I'm having an issue with the cameras in Unity. When the camera moves through any means it seems to cut my FPS in half if not more. It's not really noticeable on PC, unless I'm looking at the from from 800fps to about 150fps, however on mobile it'll cut the smooth 60fps I'm getting to 20fps on a Nexus 4. It's absolutely devastating.
Here's the properties for the camera I'm using & the script HOWEVER this issue still happens without ANY of these components and a completely reset camera component:
public class ViewDrag : MonoBehaviour
{
public Vector3 hit_position = Vector3.zero;
public Vector3 current_position = Vector3.zero;
public Vector3 camera_position = Vector3.zero;
public Vector2 min_position;
public Vector2 max_position;
float z = 0.0f;
MouseHolder holder;
hider sidebarHide;
GameObject gameStructure;
// Use this for initialization
void Start()
{
gameStructure = GameObject.FindGameObjectWithTag("GameStructure");
holder = gameStructure.GetComponent<MouseHolder>();
sidebarHide = GameObject.FindGameObjectWithTag("SidebarBG").GetComponent<hider>();
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
hit_position = Input.mousePosition;
camera_position = transform.position;
}
if (Input.GetMouseButton(0))
{
current_position = Input.mousePosition;
LeftMouseDrag();
}
if (!sidebarHide.isHidden)
{
//GetComponent<Camera2DFollow>().enabled = true;
}
if(gameStructure.GetComponent<ExecuteMovement2>().isExecuted)
{
//GetComponent<Camera2DFollow>().enabled = true;
}
}
void LeftMouseDrag()
{
// From the Unity3D docs: "The z position is in world units from the camera." In my case I'm using the y-axis as height
// with my camera facing back down the y-axis. You can ignore this when the camera is orthograhic.
//current_position.z = hit_position.z = camera_position.y;
// Get direction of movement. (Note: Don't normalize, the magnitude of change is going to be Vector3.Distance(current_position-hit_position)
// anyways.
Vector3 direction = Camera.main.ScreenToWorldPoint(current_position) - Camera.main.ScreenToWorldPoint(hit_position);
// Invert direction to that terrain appears to move with the mouse.
direction = direction * -1;
Vector3 position = camera_position + direction;
if (position.x < max_position.x && position.x > min_position.x && position.y < max_position.y && position.y > min_position.y)
{
if (!EventSystem.current.IsPointerOverGameObject() && holder.fromSlot == null )
{
if (sidebarHide.isHidden)
{
if (!gameStructure.GetComponent<ExecuteMovement2>().isExecuted)
{
//GetComponent<Camera2DFollow>().enabled = false;
transform.position = position;
}
}
}
}
}
}
Has anyone got an idea why this happens and how I can work around it if not fix it?
Through closer inspection I think it has something to do with the Canvas being screen space.. But it's kind of needed that way. Again, any workaround?
Check comments for profiler screenshot.
Problem Solved:
In the profiler I found that Canvas.SendWillRenderCanvases() was causing huge spikes. I solved the issue completely by turning off Pixel Perfect in the Canvas. Smooth as butter now.

Unity3D Third Person Controller and Animations

My problem is that a custom walk animation I have set in the third person controller of Unity3D is not shown.
The animation is imported from a FBX file with the model#walk.fbx structure. I know the animation works, because if I use it as the idle animation it shows. On the other hand, it also doesn't seem to be an issue with the controller script, as it works fine with the prototype character.
It seems that the animation being played is the one selected in the Animation component (which has 'Play Automatically' selected). Any attempts to change the animation from the third person controller work for the prototype character, but not for mine.
I don't have nor want run and jump animations. With the prototype character I set the walk animation on each of those with no adverse effects. The controller doesn't turn off animation this way, seeing that there are no log entries in the console from the third person controller script. The relevant line with the CrossFade call is getting called.
Any clues as to where I could look next? Is it more likely an issue with the controller, or with the animation? Something else completely?
Update: Below is the code of my controller. It works fine when I use the sample model of the construction worker that is provided with Unity. The lines with _animation.CrossFade are getting called at the expected times. Using Play or Blend instead doesn't help. There are no errors logged in the console.
For our custom animations however it doesn't work. I am now suspecting the issues lies with the model. Unfortunately I am not at liberty to share a sample of that model. I've asked the animator for further details on how he created the FBX export. Are there any specific settings he needs to use for the model to work in Unity? It remains odd though that the animations do work if I add them indepently to the scene.
// Require a character controller to be attached to the same game object
#script RequireComponent(CharacterController)
public var idleAnimation : AnimationClip;
public var walkAnimation : AnimationClip;
public var walkMaxAnimationSpeed : float = 0.75;
private var _animation : Animation;
enum CharacterState {
Idle = 0,
Walking = 1,
}
private var _characterState : CharacterState;
// The speed when walking
var walkSpeed = 2.0;
var speedSmoothing = 10.0;
var rotateSpeed = 500.0;
var targetPrecision = 5;
var targetMaxDistance = 200;
// The camera doesnt start following the target immediately but waits for a split second to avoid too much waving around.
private var lockCameraTimer = 0.0;
// The current move direction in x-z
private var moveDirection = Vector3.zero;
// The current x-z move speed
private var moveSpeed = 0.0;
// The last collision flags returned from controller.Move
private var collisionFlags : CollisionFlags;
// Are we moving backwards (This locks the camera to not do a 180 degree spin)
private var movingBack = false;
// Is the user pressing any keys?
private var isMoving = false;
private var isControllable = true;
private var isTargetting : boolean = false;
private var targetPoint : Vector3 = Vector3.zero;
function Awake () {
moveDirection = transform.TransformDirection(Vector3.forward);
_animation = GetComponent(Animation);
if(!_animation)
Debug.Log("The character you would like to control doesn't have animations. Moving her might look weird.");
if(!idleAnimation) {
_animation = null;
Debug.Log("No idle animation found. Turning off animations.");
}
//_animation[idleAnimation.name] = idleAnimation;
if(!walkAnimation) {
_animation = null;
Debug.Log("No walk animation found. Turning off animations.");
}
//_animation[walkAnimation.name] = walkAnimation;
}
function UpdateSmoothedMovementDirection () {
var cameraTransform = Camera.main.transform;
// Forward vector relative to the camera along the x-z plane
var forward = cameraTransform.TransformDirection(Vector3.forward);
forward.y = 0;
forward = forward.normalized;
// Right vector relative to the camera
// Always orthogonal to the forward vector
var right = Vector3(forward.z, 0, -forward.x);
var v = Input.GetAxisRaw("Vertical");
var h = Input.GetAxisRaw("Horizontal");
// Are we moving backwards or looking backwards
if (v < -0.2)
movingBack = true;
else
movingBack = false;
var wasMoving = isMoving;
isMoving = Mathf.Abs (h) > 0.1 || Mathf.Abs (v) > 0.1;
// Target direction relative to the camera
var targetDirection = h * right + v * forward;
// Lock camera for short period when transitioning moving & standing still
lockCameraTimer += Time.deltaTime;
if (isMoving != wasMoving)
lockCameraTimer = 0.0;
// We store speed and direction seperately,
// so that when the character stands still we still have a valid forward direction
// moveDirection is always normalized, and we only update it if there is user input.
if (targetDirection != Vector3.zero) {
// If we are really slow, just snap to the target direction
if (moveSpeed < walkSpeed * 0.9) {
moveDirection = targetDirection.normalized;
}
// Otherwise smoothly turn towards it
else {
moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000);
moveDirection = moveDirection.normalized;
}
}
// Smooth the speed based on the current target direction
var curSmooth = speedSmoothing * Time.deltaTime;
// Choose target speed
//* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways
var targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0);
_characterState = CharacterState.Idle;
// Pick speed modifier
targetSpeed *= walkSpeed;
_characterState = CharacterState.Walking;
moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth);
}
function UpdateTargettedMovementDirection () {
var cameraTransform = Camera.main.transform;
var wasMoving = isMoving;
isMoving = true;//Mathf.Abs (h) > 0.1 || Mathf.Abs (v) > 0.1;
// Target direction relative to the camera
// var targetDirection = h * right + v * forward;
var targetDirection = Vector3.zero;
targetDirection.x = targetPoint.x - transform.position.x;
targetDirection.z = targetPoint.z - transform.position.z;
targetDirection = targetDirection.normalized;
//Debug.Log("Target direction is " + targetDirection);
// Lock camera for short period when transitioning moving & standing still
lockCameraTimer += Time.deltaTime;
if (isMoving != wasMoving)
lockCameraTimer = 0.0;
// We store speed and direction seperately,
// so that when the character stands still we still have a valid forward direction
// moveDirection is always normalized, and we only update it if there is user input.
if (targetDirection != Vector3.zero) {
// If we are really slow, just snap to the target direction
if (moveSpeed < walkSpeed * 0.9) {
moveDirection = targetDirection.normalized;
}
// Otherwise smoothly turn towards it
else {
moveDirection = Vector3.RotateTowards(moveDirection, targetDirection, rotateSpeed * Mathf.Deg2Rad * Time.deltaTime, 1000);
moveDirection = moveDirection.normalized;
}
}
// Smooth the speed based on the current target direction
var curSmooth = speedSmoothing * Time.deltaTime;
// Choose target speed
//* We want to support analog input but make sure you cant walk faster diagonally than just forward or sideways
var targetSpeed = Mathf.Min(targetDirection.magnitude, 1.0);
_characterState = CharacterState.Idle;
// Pick speed modifier
targetSpeed *= walkSpeed;
_characterState = CharacterState.Walking;
moveSpeed = Mathf.Lerp(moveSpeed, targetSpeed, curSmooth);
}
function Update() {
if (!isControllable) {
// kill all inputs if not controllable.
Input.ResetInputAxes();
}
var distance : float = 0;
if (Input.GetMouseButtonUp(0)) {
if (isTargetting) {
isTargetting = false;
// Debug.Log("Stopped moving");
FaceCamera();
} else {
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var layerMask = 1 << 8; // Terrain is layer 8
var hit : RaycastHit;
Physics.Raycast(Camera.main.transform.position, ray.direction, hit, 1000, layerMask);
distance = Vector3.Distance(transform.position, hit.point);
if (distance <= targetMaxDistance && hit.point != Vector3.zero) {
targetPoint = hit.point;
isTargetting = true;
// Debug.Log("Mouse up at hit " + hit.point + " at distance " + distance);
} else {
isTargetting = false;
// Debug.Log("Ignored mouse up at hit " + hit.point + " at distance " + distance);
}
}
}
if (isTargetting) {
// Debug.Log("Moving to " + targetPoint);
distance = Vector3.Distance(transform.position, targetPoint);
if (distance < targetPrecision) {
// Debug.Log("Reached point " + targetPoint + " at distance " + distance);
isTargetting = false;
FaceCamera();
} else {
UpdateTargettedMovementDirection();
}
} else {
UpdateSmoothedMovementDirection();
}
// Calculate actual motion
var movement = moveDirection * moveSpeed;
movement *= Time.deltaTime;
// Move the controller
var controller : CharacterController = GetComponent(CharacterController);
collisionFlags = controller.Move(movement);
// ANIMATION sector
if (_animation) {
if (controller.velocity.sqrMagnitude < 0.1) {
_animation.CrossFade(idleAnimation.name);
} else {
//_animation[walkAnimation.name].speed = Mathf.Clamp(controller.velocity.magnitude, 0.0, walkMaxAnimationSpeed);
_animation.CrossFade(walkAnimation.name);
}
} else {
Debug.Log("Animation is null!");
}
// ANIMATION sector
// Set rotation to the move direction
transform.rotation = Quaternion.LookRotation(moveDirection);
}
function OnControllerColliderHit (hit : ControllerColliderHit ) {
// Debug.DrawRay(hit.point, hit.normal);
if (hit.moveDirection.y > 0.01)
return;
}
function GetSpeed () {
return moveSpeed;
}
function GetDirection () {
return moveDirection;
}
function IsMovingBackwards () {
return movingBack;
}
function GetLockCameraTimer () {
return lockCameraTimer;
}
function IsMoving () : boolean {
return Mathf.Abs(Input.GetAxisRaw("Vertical")) + Mathf.Abs(Input.GetAxisRaw("Horizontal")) > 0.5;
}
function Reset () {
gameObject.tag = "Player";
}
function FaceCamera() {
var cameraTransform = Camera.main.transform;
// Forward vector relative to the camera along the x-z plane
var forward = cameraTransform.TransformDirection(Vector3.forward);
forward.y = 0;
forward = forward.normalized;
moveDirection = -forward;
}
Update 2: The settings used to create the animations are in these screenshots. Are they correct?
Not (yet :-) an answer but I need more space and images.
Since 3.5 Unity3d the way to handle imports based on animation#model.fbx notation has changed and some people reported trouble (s. for example BIG Unity 3.5.0f1 problem with Skinned Rig - Major FAIL). The problem arises when a 2nd root bone comes to play but I could solve this by dragging the animations to the model file prefab (most of my animations are contained in the model and the remaining 2 are no big pain).
Just to be really sure that I understood your answer in the comments section right, you have something like this:
That means:
Within the character model the animations array contains all animations
The number of bones and all names are exactly like in your prototype character
If you open an animation view, you can see a read-only list of all animations of the character selected in hierarchy view
Assuming this is fine some more suggestions:
I can't see any place in the code where you set WrapMode.Loop or animation speed. Are you sure it is configured as Loop in inspector and is not overwritten somewhere.
CrossFade with no parameters assumes 0.3 seconds
What happens after the cross fade call? Does the DefaulTake stops playing?
Can you drag the Walk animation as default
Do you use different animation layers?
What output do you get when you set up Debug.Log ("Walk: " + player.animation.IsPlaying ("Walk"));
[Update]
Let's look at the import settings. Do you have Split Animations
checked and are there maybe wrong values entered at Start and
End like 1-1?
Regarding Toggling of IsPlaying: Please create more output about the AnimationState properties. Most notable speed, length, enabled, weight, ... I have a suspicion that the animation is too short or played too fast.
A walk animation that is no bone animation sounds a bit strange. On the other hand console would cry out loud if bone names are not matching. So I assume there is no problem now.
That is strange, can you post the source&demo?
You can try to check:
Check if the animation names and properties are set correctly in the editor.
Create an object without the controller and make sure the animations were imported correctly.