RigidbodyConstraints.Freeze - broken?

I have created a player move/action script based on mouse0 held down.

Currently clicking or holding the mouse 0 on the ground causes the model to move/animations to fire.
If I let go the model stops, animation returns to default.

If I click/hold on a ‘shootable’ object, model stops and plays the shooting anim.
If I let go, the anim stops.

Problem<<

If I click and hold on ground, and drag through/on a shootable object , the player remains in the ‘walking state’ and continues to play the walking anim.

Like wise if I click and hold, on a shootable object, the shooting anim fires, If I drag outside of the shootable, namely the ground, the player starts moveng as per the walking transform, but continues to play the shooting anim.

I know the raycast is somehow updating what my cursor is over, as the model starts to move but the animation is not updating to the walk from the shoot. reflect this change. like wise the walk, does not seem to switch to the shoot on mouse over of a shootable.

I suspect it may be the transitions in the animator, and the boolean parameter updates to the animator.

Currently my animations and parameters are as follows

Animations:

Default Pose (standing still)
walking (…walking)
shooting (eh…shooting)

Parameters:

IsWalking
IsShooting

Setup is as follows:

default —> walking (requires IsWalking true)
walking—>default (requires IsWalking false)

default ----> shooting (requires IsShooting true)
shooting —> default (requires IsShooting false)

I have a number of Debug lines in my code from working on the shooting detection. I’ve left them in.
Any ideas would be helpful or suggestions on what to change.

Code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

namespace CompleteProject
{



    public class PlayerMoveClick2 : MonoBehaviour
    {

   
        private Animator anim;
        private NavMeshAgent navMeshAgent;
        Rigidbody playerRigidbody;
        int floorMask;
        private bool walking;
        private bool shooting;
        private float shootDur;
        private float shootNext;
        private bool enemyClicked;
        private Transform targetedEnemy;


        // Use this for initialization
        void Awake ()
        {
            anim = GetComponent<Animator> ();
            navMeshAgent = GetComponent<NavMeshAgent> ();
            //floorMask = LayerMask.GetMask ("Shootable");
            playerRigidbody = GetComponent <Rigidbody> ();
            shootDur = 0.5f;
            shootNext = 0f;
            shooting = false;
        }
       
        // Update is called once per frame
        void Update ()
        {
            Debug.Log("======VOID UPDATE START=======");

           
            if (Input.GetMouseButton(0))
            {
                Debug.Log("LEFT MOUSE HELD/PRESSED");
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit moveHit;
               
               
                if (Physics.Raycast(ray, out moveHit, 100f))   //removed floorMask at end
                {
                    Debug.Log("Raycast == HIT");
                    if (moveHit.collider.CompareTag("Enemy"))
                    {

                        targetedEnemy = moveHit.transform;
                        enemyClicked = true;
                        Debug.Log("HIT Target == Enemy ");
                        shootWep1();
                       
                    }

                    else   
                    {
                        Debug.Log("HIT Target == NOT Enemy");
                        Vector3 moveTarget = moveHit.point - transform.position;
                        moveTarget.y = 0f;
                        Quaternion newRotation = Quaternion.LookRotation(moveTarget);
                        playerRigidbody.MoveRotation (newRotation);
                        walking = true;
                        //shooting = false;
                        enemyClicked = false;
                        navMeshAgent.destination = moveHit.point;
                        anim.SetBool ("IsWalking", walking);
                        anim.SetBool ("IsShooting", shooting);
                        navMeshAgent.Resume();
                       
                                       
                    }
                }
            }
            else
            {
                Debug.Log("LEFT MOUSE not HELD/PRESSED");
                walking = false;
                shooting = false;
                anim.SetBool ("IsWalking", walking);
                anim.SetBool ("IsShooting", shooting);
                navMeshAgent.Stop();
            }
           
           
            //if (enemyClicked == true)
            //{
            //    Debug.Log("enemyClicked == true SUCCESS");
            //    shooting = true;
            //    walking = false;
            //    anim.SetBool ("IsWalking", walking);
            //    navMeshAgent.Stop();
            //    shootWep1();
            //}
               
           
//mouse not pressed so stand still

            //else
            //{
            //    walking = false;
            //    //shooting = false;
            //    anim.SetBool ("IsWalking", walking);
            //    //anim.SetBool ("IsShooting", shooting);
            //    navMeshAgent.Stop();
            //}
       
       
        Debug.Log("=======VOID UPDATE END========");
        }
       
        private void shootWep1()
        {
            Debug.Log("shootWep1 CALLED SUCCESSFULLY");
            if (enemyClicked == true)
            {
                Debug.Log("enemyClicked == STILL TRUE");
                if (Time.time > shootNext)                //ShootDur = 0.5f ShootNext= ? Time.time = current time in frame since game start
                {
                    Debug.Log("-->>TIME TO SHOOT<<--  Time.time > shootNext");
                    shootNext = Time.time + shootDur;
                    //Call shooting anim, perform shoot actions
                    //navMeshAgent.Stop();
                    //walking = false;
                    //anim.SetBool ("IsWalking", walking);
                    shooting = true;
                    anim.SetBool ("IsShooting", shooting);
                   
                }
                          
                else
                {
                 
                    Debug.Log("-->>CAN'T SHOOT YET <<-- Time.time NOT > shootNext");
                    if (shootNext < Time.time + shootDur)
                    {   
                        Debug.Log("Waiting for current shoot animation to finish");
                        shooting = true;
                        Debug.Log("Making shooting = true so animation continues");
                    }
                    else
                    {
                    Debug.Log("Shooting Animation not playing anymore");
                    //navMeshAgent.Stop();
                    //walking = false;
                    //anim.SetBool ("IsWalking", walking);
                    shooting = false;
                    anim.SetBool ("IsShooting", shooting);
                    Debug.Log("Stopped shooting animation");

                    }
                }
            }
       
        Debug.Log("shootWep1 === FINISHED");
        }  
       
       
       
       
    }

}

Well I got a second ounce of courage to try and debug it. SUCCESS!

For those that may want to reuse the code (in a working state). I did the following.

A) added animation transitions as follows:

walking → shooting (requires IsShooting true, IsWalking false)
shooting → walking (requires IsShooting false, IsWalking true)

B) code updates.

Changed line 73 from:

//shooting = false;

Changed line 73 to:

shooting = false;


Inserted some lines in: private void shootWep1() function, near top

        private void shootWep1()
        {
            Debug.Log("shootWep1 CALLED SUCCESSFULLY");
            if (enemyClicked == true)
            {
                shooting = true;
                walking = false;
                navMeshAgent.Stop();
                anim.SetBool ("IsShooting", shooting);
                anim.SetBool ("IsWalking", walking);
                Debug.Log("enemyClicked == STILL TRUE");
                if (Time.time > shootNext)                //ShootDur = 0.5f ShootNext= ? Time.time = current time in frame since game start
                {
                    Debug.Log("-->>TIME TO SHOOT<<--  Time.time > shootNext");
                    shootNext = Time.time + shootDur;
                    //Call shooting anim, perform shoot actions
                    //navMeshAgent.Stop();
                    //walking = false;
                    //anim.SetBool ("IsWalking", walking);
                    shooting = true;
                    anim.SetBool ("IsShooting", shooting);
                   
                }
                          
                else
                {
                 
                    Debug.Log("-->>CAN'T SHOOT YET <<-- Time.time NOT > shootNext");
                    if (shootNext < Time.time + shootDur)
                    {   
                        Debug.Log("Waiting for current shoot animation to finish");
                        shooting = true;
                        Debug.Log("Making shooting = true so animation continues");
                    }
                    else
                    {
                    Debug.Log("Shooting Animation not playing anymore");
                    //navMeshAgent.Stop();
                    //walking = false;
                    //anim.SetBool ("IsWalking", walking);
                    shooting = false;
                    anim.SetBool ("IsShooting", shooting);
                    Debug.Log("Stopped shooting animation");

                    }
                }
            }
       
        Debug.Log("shootWep1 === FINISHED");
        }

Now I just have to fix the rotation on shoot, and it should be finished. update to follow

Ok having trouble passing the quaternion rotation onto my shoot function. Here’s the full code with no debugs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

namespace CompleteProject
{



    public class PlayerMoveClick2 : MonoBehaviour
    {

   
        private Animator anim;
        private NavMeshAgent navMeshAgent;
        Rigidbody playerRigidbody;
        int floorMask;
        private bool walking;
        private bool shooting;
        private float shootDur;
        private float shootNext;
        private bool enemyClicked;
        private Transform targetedEnemy;


        // Use this for initialization
        void Awake ()
        {
            anim = GetComponent<Animator> ();
            navMeshAgent = GetComponent<NavMeshAgent> ();
            playerRigidbody = GetComponent <Rigidbody> ();
            shootDur = 0.5f;
            shootNext = 0f;
            shooting = false;
        }
       
        // Update is called once per frame
        void Update ()
        {
            if (Input.GetMouseButton(0))
            {
                Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
                RaycastHit moveHit;
                if (Physics.Raycast(ray, out moveHit, 100f))   //removed floorMask at end
                {
                    if (moveHit.collider.CompareTag("Enemy"))
                    {
                        targetedEnemy = moveHit.transform;
                        Vector3 moveTarget = moveHit.point - transform.position;
                        moveTarget.y = 0f;
                        Quaternion newRotation = Quaternion.LookRotation(moveTarget);
                        playerRigidbody.MoveRotation (newRotation);
                        enemyClicked = true;
                        shootWep1(moveTarget);
                    }

                    else   
                    {
                        Vector3 moveTarget = moveHit.point - transform.position;
                        moveTarget.y = 0f;
                        Quaternion newRotation = Quaternion.LookRotation(moveTarget);
                        playerRigidbody.MoveRotation (newRotation);
                        walking = true;
                        shooting = false;
                        enemyClicked = false;
                        navMeshAgent.destination = moveHit.point;
                        anim.SetBool ("IsWalking", walking);
                        anim.SetBool ("IsShooting", shooting);
                        navMeshAgent.Resume();                 
                    }
                }
            }
            else
            {
                walking = false;
                shooting = false;
                anim.SetBool ("IsWalking", walking);
                anim.SetBool ("IsShooting", shooting);
                navMeshAgent.Stop();
            }
        }
       
        private void shootWep1(Vector3 moveTarget)
        {
            if (enemyClicked == true)
            {
                transform.LookAt(targetedEnemy);
               
               
                shooting = true;
                walking = false;
                navMeshAgent.Stop();
                anim.SetBool ("IsShooting", shooting);
                anim.SetBool ("IsWalking", walking);
                if (Time.time > shootNext)                //ShootDur = 0.5f ShootNext= ? Time.time = current time in frame since game start
                {
                    shootNext = Time.time + shootDur;
                    shooting = true;
                }
                          
                else
                {
                    if (shootNext < Time.time + shootDur)
                    {   
                        shooting = true;
                    }
                    else
                    {
                        shooting = false;
                        anim.SetBool ("IsShooting", shooting);
                    }
                }
            }
        }    
    }
}

I have the transform.LookAt(targetedEnemy); which works with the annoying 180 insta-flip.

I’m trying to somehow pass the quaternion info obtained from a successfully mouse0 on an enemy to my function.

Lines 60 - 63 handle rotation while walking. I’ve tried duplicating them in my shootWep1 funtion and get errors about outside of scope. I’ve tried to correct for thatonly to get errors I don’t fully know how to solve or really understand.

I’m sure there is a way to pass the information to the function and have it perform it but I’m simply at the trial and error stage hoping I might get something that works. Kinda stuck now.

Well I’m stuck…again. I’ve been able to get the player to rotate at what their shooting at (had to enable Navmesh.Resume(); instead of stop)

Now trying to freeze their postion while their shooting. I can’t seem to make it work. I’ve placed

playerRigidbody.constraints = RigidbodyConstraints.FreezePositionX | RigidbodyConstraints.FreezePositionZ;

before my shootWep1(); call, as well as inside the ‘ok to shoot section’, and the 'waiting for shoot animation to finish 'section. but my player just seems to ignore it and will continue to move along the X/Z axis as if I had never tried to freeze it when ever I click/hold down mouse0. I have not called RigidbodyConstraints.none anywhere.

Why might the nav mesh be moving about these axis when I’ve specifically frozen them?

edit: I should note I have tried changing the freeze to before and after my MoveRotation lines with no success

ok there is something definitely wrong with this constraints thing. I put

playerRigidbody.constraints = RigidbodyConstraints.FreezePosition;

Right after Update.

        // Update is called once per frame
        void Update ()
        {
            playerRigidbody.constraints = RigidbodyConstraints.FreezePosition;
        
            if (Input.GetMouseButton(0))
            {

My player still can move around. every update player should be frozen, no other reference to constraints is made.
does navMeshAgent .destination .Resume(); override constraints?

EDIT: Could it be that be that in the Inspector I have constraints set, and they are overriding anything I put in code? ie Inspector is position: Y selected, rotation X Z selected and Unity will always use those constraints and ignore anything I put in code?

Should I deselect them all, and code the above at awake, instead?

Yeah something not right with constraints & Unity. I turned on ALL constraints for rotation and position in the inspector,

added: playerRigidbody.constraints = RigidbodyConstraints.FreezePosition | RigidbodyConstraints.FreezeRotation;

to my awake function, and my player can still move around, walk, go in circles even though everything is frozen.

    public class PlayerMoveClick2 : MonoBehaviour
    {

   
        private Animator anim;
        private NavMeshAgent navMeshAgent;
        Rigidbody playerRigidbody;
        int floorMask;
        private bool walking;
        private bool shooting;
        private float shootDur;
        private float shootNext;
        private bool enemyClicked;
        //private Transform targetedEnemy;



        // Use this for initialization
        void Awake ()
        {
            anim = GetComponent<Animator> ();
            navMeshAgent = GetComponent<NavMeshAgent> ();
            playerRigidbody = GetComponent <Rigidbody> ();
            playerRigidbody.constraints = RigidbodyConstraints.FreezePosition | RigidbodyConstraints.FreezeRotation;

Well, sent a bug report since no one here seems to be able to help