Third Person controller
Hello everyone. I finally got most of the code for third person controller working as far as animations goes, but its still having issues. I ended up scrapping everything and started over.
Here is the problem.
1) No errors are showing in Engine for this script, yet... A: Gravity/Grounded settings are not working. B: Jump power settings are not working at all. C: Character falls slowly when running off edge/after jump: D: Character stays in jump if holding space-bar down.
Additional issue:
2) One of the key features i also need this script to do is allow me to double hit the left control key the change states from running to walking and double hit again to change back from running to walk. This way i do not need to "hold down the left ctrl" or any other button to remain in a constant run or walk state. Currently this code allows me to use either WASD or Arrows which i wish to keep.
If anyone here knows how to fix this script and willing to volunteer the assist so it works with my Player Animator, it would be much appreciated. (A good percent of this code simply is not working and I do not understand where to place additional functions such as crouching, swimming etc.).
Here is the code:
public Animator anim;
public Rigidbody Rb;
public float speed;
public float inputH = 20f;
public float inputV = 50f;
private bool run;
private bool jump;
[System.Serializable]
public class MoveSettings
{
public float jumpVel = 20;
public float distToGrounded = 1.1f;
public LayerMask ground;
}
[System.Serializable]
public class PhysSettings
{
public float downAccel = 1.5f;
}
[System.Serializable]
public class InputSettings
{
public float InputDelay = 0f;
}
public MoveSettings moveSetting = new MoveSettings();
public PhysSettings physSetting = new PhysSettings();
public InputSettings inputSetting = new InputSettings();
Vector3 velocity = Vector3.zero;
// Use this for initialization
void Start()
{
anim = GetComponent<Animator>();
Rb = GetComponent<Rigidbody>();
run = false;
jump = false;
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.LeftControl)) // want to changee this to double click to swicth from walk to run and back again.
{
run = true;
}
else
{
run = false;
}
if (Input.GetKey(KeyCode.Space))
{
jump = true;
}
else
{
jump = false;
}
velocity.y = moveSetting.jumpVel;
{
velocity.y -= physSetting.downAccel;
}
inputH = Input.GetAxis("Horizontal");
inputV = Input.GetAxis("Vertical");
Rb.velocity = transform.TransformDirection(velocity);
anim.SetFloat("inputH", inputH);
anim.SetFloat("inputV", inputV);
anim.SetBool("run", run);
anim.SetBool("jump", jump);
float moveX = inputH * 20f * Time.deltaTime;
float moveZ = inputV * 50f * Time.deltaTime;
if (moveZ <= 0f)
{
moveX = 0f;
}
else if (run)
{
moveX *= 6f;
moveZ *= 6f;
}
Rb.velocity = new Vector3(moveX, 0f, moveZ * speed);
///Need to add physics.
}
bool Grounded()
{
return Physics.Raycast(transform.position, Vector3.down, moveSetting.distToGrounded, moveSetting.ground);
}
}
Also I am not entirely sure I did not do something wrong here in the Animator.
Note: I don't want to use the Character controllers provided in the engine because of how buggy they are.
Answer by Rhombuster · Mar 29, 2017 at 04:45 AM
Physics are typically done in FixedUpdate. See here: https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html
I think one of your main issues is that you are directly setting the velocity of your character. You are also treating the physics in a similar way to transforms. I think most of your issues spawn from this:
Rb.velocity = new Vector3(moveX, 0f, moveZ * speed);
You are constantly setting your player's y velocity to 0. Here is some cleaned up code to get you started. All it has is jump, but it might help you figure out the rest:
void Update() {
if (Input.GetKey(KeyCode.LeftControl)) // want to changee this to double click arrow to swith from walk to run
{
run = true;
} else {
run = false;
}
if (Input.GetKey(KeyCode.Space)) {
jump = true;
} else {
jump = false;
}
inputH = Input.GetAxis("Horizontal");
inputV = Input.GetAxis("Vertical");
}
void FixedUpdate() {
ApplyGravity();
if(jump) {
Rb.AddForce(Vector3.up * moveSetting.jumpVel);
}
}
void ApplyGravity() {
Rb.AddForce(Vector3.up * -physSetting.downAccel);
}
I poll for input in Update because fixed update can miss inputs which will feel buggy and weird. If your player starts to fall over, try freezing rotation constraints on the rigidbody. The rigidbody also has its own gravity, which you will want to disable if you use a custom one like this.
Let me know if you have any other questions.
I had something similar before fro line 50 down as follows:
void Update() {
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.LeftControl))
{
run = true;
}
else
{
run = false;
}
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.Space))
{
jump = true;
}
else
{
jump = false;
}
velocity.y = moveSetting.jumpVel;
{
velocity.y -= physSetting.downAccel;
}
inputH = Input.GetAxis("Horizontal");
inputV = Input.GetAxis("Vertical");
Rb.velocity = transform.TransformDirection(velocity);
anim.SetFloat("inputH", inputH);
anim.SetFloat("inputV", inputV);
anim.SetBool("run", run);
anim.SetBool("jump", jump);
float moveX = inputH * 20f * Time.deltaTime;
float moveZ = inputV * 50f * Time.deltaTime;
}
void FixedUpdate() {
ApplyGravity();
if (jump)
{
Rb.AddForce(Vector3.up * moveSetting.jumpVel);
}
}
void ApplyGravity() {
Rb.AddForce(Vector3.up * -physSetting.downAccel);
}
}
The problem is i then get the following errors.
1) Assets/Scripts/PlayerControl.cs(85,15): warning CS0219: The variable moveX' is assigned but its value is never used. 2) Assets/Scripts/PlayerControl.cs(86,15): warning CS0219: The variable
moveZ' is assigned but its value is never used.
These are both warnings. It's just telling you that you have moveX and moveZ in your code, but they do not do anything.
You should remove the line where you set the velocity:
Rb.velocity = transform.TransformDirection(velocity);
You'll need to create code to handle the horizontal movement. You can use AddForce inside FixedUpdate with your two input axes (inputH, inputV).
Sorry, I responded in wrong spot. O$$anonymous$$< so I think I am comprehending what you meant, But there is two issues now in the following code. If i turn off gravity in Rigid Body, character shoots right up. If i turn it on, character jumps up and falls fairly well, but, all movement from position ceases to work. Animations do play however.
public Animator anim; public Rigidbody Rb;
public float speed;
public float inputH = 20f;
public float inputV = 50f;
private bool run;
private bool jump;
[System.Serializable]
public class $$anonymous$$oveSettings
{
public float jumpVel = 20;
public float distToGrounded = 1.1f;
public Layer$$anonymous$$ask ground;
}
[System.Serializable]
public class PhysSettings
{
public float downAccel = 1.5f;
}
[System.Serializable]
public class InputSettings
{
public float InputDelay = 0f;
}
public $$anonymous$$oveSettings moveSetting = new $$anonymous$$oveSettings();
public PhysSettings physSetting = new PhysSettings();
public InputSettings inputSetting = new InputSettings();
Vector3 velocity = Vector3.zero;
// Use this for initialization
void Start()
{
anim = GetComponent<Animator>();
Rb = GetComponent<Rigidbody>();
run = false;
jump = false;
}
// Update is called once per frame
void Update()
{
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.LeftControl))
{
run = true;
}
else
{
run = false;
}
if (Input.Get$$anonymous$$ey($$anonymous$$eyCode.Space))
{
jump = true;
}
else
{
jump = false;
}
Rb.AddForce(Vector3.up * moveSetting.jumpVel);
{
velocity.y -= physSetting.downAccel;
}
inputH = Input.GetAxis("Horizontal");
inputV = Input.GetAxis("Vertical");
anim.SetFloat("inputH", inputH);
anim.SetFloat("inputV", inputV);
anim.SetBool("run", run);
anim.SetBool("jump", jump);
float moveX = inputH * 20f * Time.deltaTime;
float moveZ = inputV * 50f * Time.deltaTime;
if (moveZ <= 0f)
{
moveX = 0f;
}
else if (run)
{
moveX *= 6f;
moveZ *= 6f;
}
}
void FixedUpdate()
{
ApplyGravity();
if (jump)
{
Rb.AddForce(Vector3.up * moveSetting.jumpVel);
}
}
void ApplyGravity() {
Rb.AddForce(Vector3.up * -physSetting.downAccel);
}
}