I am very new to Unity and I never coded in C# before neither have I used Unity in the past. All I know is Java and Python. I knew Java since senior year of high school now I am a sophomore in college. I made my project, which consists of my human character, which is supposed to shoot bullets at 12 jaguars. I already implemented all of this from the 2d UFO sample Unity gives us. I have a png picture for my bullet. I really do not know how to implement a bullet. I am required to have the bullet shoot out in two directions. I am starting off gradually by learning how to basic shoot (one direction). I referred to this link and added it to my program and it will not compile after I added the bullet code. I create a sphere into the Unity program as the website said to do and I set the image as the png bullet.
https://unity3d.com/learn/tutorials/temas/multiplayer-networking/shooting-single-player
Now here is my code. I downloaded the free latest version of Unity by the way. My game is 2D by the way. It is just cartoons.
using UnityEngine;
using System.Collections;
//Adding this allows us to access members of the UI namespace including Text.
using UnityEngine.UI;
public class CompletePlayerController : MonoBehaviour {
public float speed; //Floating point variable to store the player's movement speed.
public Text countText; //Store a reference to the UI Text component which will display the number of pickups collected.
public Text winText; //Store a reference to the UI Text component which will display the 'You win' message.
private Rigidbody2D rb2d; //Store a reference to the Rigidbody2D component required to use 2D Physics.
private int count; //Integer to store the number of pickups collected so far.
public GameObject bulletPrefab;
public Transform bulletSpawn;
// Use this for initialization
void Start()
{
//Get and store a reference to the Rigidbody2D component so that we can access it.
rb2d = GetComponent<Rigidbody2D> ();
//Initialize count to zero.
count = 0;
//Initialze winText to a blank string since we haven't won yet at beginning.
winText.text = "";
//Call our SetCountText function which will update the text with the current value for count.
SetCountText ();
}
//FixedUpdate is called at a fixed interval and is independent of frame rate. Put physics code here.
void FixedUpdate()
{
//Store the current horizontal input in the float moveHorizontal.
float moveHorizontal = Input.GetAxis ("Horizontal");
//Store the current vertical input in the float moveVertical.
float moveVertical = Input.GetAxis ("Vertical");
//Use the two store floats to create a new Vector2 variable movement.
Vector2 movement = new Vector2 (moveHorizontal, moveVertical);
//Call the AddForce function of our Rigidbody2D rb2d supplying movement multiplied by speed to move our player.
rb2d.AddForce (movement * speed);
if (!isLocalPlayer)
{
return;
}
var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f;
transform.Rotate(0, x, 0);
transform.Translate(0, 0, z);
if (Input.GetKeyDown(KeyCode.Space))
{
Fire();
}
}
void Fire()
{
// Create the Bullet from the Bullet Prefab
var bullet = (GameObject)Instantiate (
bulletPrefab,
bulletSpawn.position,
bulletSpawn.rotation);
// Add velocity to the bullet
bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 6;
// Destroy the bullet after 2 seconds
Destroy(bullet, 2.0f);
}
public override void OnStartLocalPlayer ()
{
GetComponent<MeshRenderer>().material.color = Color.blue;
}
//OnTriggerEnter2D is called whenever this object overlaps with a trigger collider.
void OnTriggerEnter2D(Collider2D other)
{
//Check the provided Collider2D parameter other to see if it is tagged "PickUp", if it is...
if (other.gameObject.CompareTag ("PickUp"))
{
//... then set the other object we just collided with to inactive.
other.gameObject.SetActive(false);
transform.localScale += new Vector3(0.1f, 0.1f, 0);
//Add one to the current value of our count variable.
count = count + 1;
//Update the currently displayed count by calling the SetCountText function.
SetCountText ();
}
}
//This function updates the text displaying the number of objects we've collected and displays our victory message if we've collected all of them.
void SetCountText()
{
//Set the text property of our our countText object to "Count: " followed by the number stored in our count variable.
countText.text = "Count: " + count.ToString ();
//Check if we've collected all 12 pickups. If we have...
if (count >= 12)
//... then set the text property of our winText object to "You win!"
winText.text = "You win!";
}
}
Other class
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour {
public GameObject player; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start ()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate ()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
transform.position = player.transform.position + offset;
}
}
You need to follow all the steps in the tutorial link you shared. Looks like you have copied pieces of code and used it in your controller class. OnStartLocalPlayer is marked as overridden, but it is not in Monobehaviour. It is defined in NetworkBehaviour. You have an error due to this. As mentioned in the other comments, the console error tells you where the problem is.
Related
I am trying to create a minigame similar to the fishing mechanism in Stardew Valley. I have two boundaries which are empty objects positioned at each end of a rectangle to keep the fish and the hook inside of the zone. When I run my script, the fish spawns at the bottom boundary and moves up instead of the position it is initially in. The hook generates at the bottom boundary and doesn't move upon user input.
Here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FishingMiniGame : MonoBehaviour
{
//Make the Egg move
[Header("Fishing Area")]
[SerializeField] Transform topBounds;
[SerializeField] Transform bottomBounds;
[Header("Fish Settings")]
[SerializeField] Transform Fish;
[SerializeField] float smoothMotion = 3f;
[SerializeField] float fishTimeRandomizer = 3f;
float fishPosition;
float fishSpeed;
float fishTimer;
float fishTargetPosition;
[Header("Hook Settinds")]
[SerializeField] Transform Hook;
[SerializeField] float HookSize = .18f;
[SerializeField] float HookSpeed = .1f;
[SerializeField] float HookGravity = .05f;
float hookPosition;
float hookPullVelocity;
private void FixedUpdate()
{
MoveFish();
MoveHook();
}
private void MoveHook()
{
if(Input.GetMouseButtonDown(0))
{
//increase our pull velocity
hookPullVelocity += HookSpeed * Time.deltaTime; //raises out hook
}
hookPullVelocity -= HookGravity * Time.deltaTime;
hookPosition += hookPullVelocity;
hookPosition = Mathf.Clamp(hookPosition, 0, 1); //keep the jook withon bounds
Hook.position = Vector3.Lerp(bottomBounds.position, topBounds.position, hookPosition);
}
private void MoveFish()
{
//based on timer, pick random position
//move fish to that position smoothly
fishTimer -= Time.deltaTime;
if(fishTimer < 0)
{
//pick a new target position
//reset timer
fishTimer = Random.value * fishTimeRandomizer;
fishTargetPosition = Random.value;
}
fishPosition = Mathf.SmoothDamp(fishPosition, fishTargetPosition, ref fishSpeed, smoothMotion);
Fish.position = Vector3.Lerp(bottomBounds, topBounds, fishPosition);
}
}
Well, first, making all the code in one script will be confuse. Try giving that fish its own script and game object.
Plus, take a look into Lerp. I think you are missundertanding how to use it. It takes 3 parameters with a being the original Vector3, so your current hook or fish position, b is your Vector3 target position, and t is the step or timestep. Should be delta or delta*someMultiplier.
What #MickyD said is also true, input should be performed during Update(), but that will not fix you code. Update(), FixedUpdate() and LateUpdate() are kinda the same but they run always in that order: Update -> FixedUpdate -> LateUpdate. So keep that in mind.
By the way, your gravity aplies every frame, so your hook is fighting against it even when you are lifting, resulting in half the force being neutralized. Making the gravity only apply on an else after your input will give you a much clear control of forces.
I've followed a C# in Unity tutorial to create a simple Space Invaders game. I'm now trying to understand the different functions being used.
There is this class called PlayerController. It also defines a shot gameobject, a field which is then supplied with a bullet prefab:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private Transform player;
public float speed;
public float maxBound, minBound;
public GameObject shot;
public Transform shotSpawn;
public float fireRate;
private float nextFire;
// Start is called before the first frame update
void Start()
{
player = GetComponent<Transform> ();
}
// Update is called once per frame
void FixedUpdate()
{
float h = Input.GetAxis ("Horizontal");
if (player.position.x < minBound && h < 0)
h = 0;
else if (player.position.x > maxBound && h > 0)
h = 0;
player.position += Vector3.right * h * speed;
}
void Update()
{
if (Input.GetButton("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
}
}
}
The bullet gameobject used the class BulletController:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletController : MonoBehaviour
{
private Transform bullet;
public float speed;
// Start is called before the first frame update
void Start()
{
bullet = GetComponent<Transform>();
}
void FixedUpdate()
{
bullet.position += Vector3.up * speed;
if (bullet.position.y >= 10)
Destroy(gameObject);
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Enemy")
{
Destroy(other.gameObject);
Destroy(gameObject);
PlayerScore.playerScore++;
}
else if (other.tag == "Base")
Destroy(gameObject);
}
}
From what I understand, a Transform object has values for position, rotation and scale.
So first, what does declaring x = GetComponent; do?
Second, where does "shotSpawn" takes its values from? From the object to which the code is applied to?
Third, the bullet gets instantiated exactly at the center of the square serving as the player ship's body, but I want it start higher at the y axis so it starts at the end of the cannon shape. It also seems to graphically intersect with the ship's body, so I wanted to move it slightly into the z axis. So how can you write that? I tried adding to the value of shotSpawn.position but it keeps declaring errors.
Thanks in advance.
A GetComponent means basically just grabbing a component of an object. Take a simple example: The Main Camera has a lot of components:
1.1. A Transform component. This component is used, as you understood, to define the position, rotation and scaling of an object
1.2. A Camera component. This has plenty of fields
1.3. A Flare Layer component.
etc.
These components can be grabbed via script. The reason developers use this is for their properties. For example, by saying Transform playerTransformComp = player.GetComponent<Transform>();, you will be able to write playerTransformComp.position. position is a property of objects of type Transform.
I don't think that the GetComponent you saw in the tutorial are useful because every game object has a transform component anyway, so if they declared the player as public GameObject player;, then used player.transform.position instead, it would have been way easier. In fact, I don't think it even makes sense to declare something as Transform, and then grabbing the Transform component. As #BugFinder said in your previous post, the tutorial is pretty bad overall.
shotSpawn takes its values from... itself! It is a public object, so I'm assuming you dragged & dropped the shotSpawn object from the scene into the script's fields. This means that the shotSpawn object from the script is the object you dragged & dropped on the script's fields. You can use all of its features and the dragged & dropped object will be affected. Thus, you can use shotSpawn.position and shotSpawn.rotation. I might be repeating myself here for a little bit, but please notice that shotSpawn is a Transform object, therefore you can use a typical Transform object's properties.
The documentation on Transform.position (as well as the one on Transform.rotation say you have to use Vector3 objects to add or substract values to them.
One would do shotSpawn.position + new Vector3(10f, 5f, 10f).
Naturally, you can also do
value = new Vector3(10f, 5f, 10f);
and then Instantiate(shot, shotSpawn.position + value, shotSpawn.rotation);
Also, please (for the future), try to ask one question per post, otherwise people will ignore your question or even flag it and it will be deleted. I was once like you, so I wouldn't do that, but please take this into consideration when making further posts.
I am trying to set up control of Player game object by UI buttons.
2d top down view scene.
I want to transfer Player object smoothly on fixed distance (0.8 for Axix X for left-right direction and 2.4 for up-down)when I release left/right/up/down ui buttons.
Here i found code for smooth movement but there Player is moving all the time while ui button is pressed.
Can you help me to make it move on mouse up (pointer up) and to move for public x= 0.8f for left/right, and public y = 2.4f for up/down
And at the same time i want to use different speed (peblic) for moves on x and y Axis
Its ok if it should be totally other script using smth like transform.translate
Kindly guide to for any possible solution for this. Thanks
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
public class PlayerControl : MonoBehaviour
{
float movX;
float movY;
Rigidbody2D rb;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
movX = CrossPlatformInputManager.GetAxisRaw("Horizontal");
movY = CrossPlatformInputManager.GetAxisRaw("Vertical");
rb.velocity = new Vector2(movX * 1, movY * 1);
}
}
This script can be moved by the WASD keys.
This should move your gameObject by the requested amount over x amount of time(speed).
Currently it can be only moved when it'S reached its destionation but you can easily modify this :), by stopping the coroutine
using System.Collections;
using UnityEngine;
public class PlayerControl : MonoBehaviour
{
// We gonna move by WASD keys
[Header("Speed & Movement settings")]
[SerializeField]
float Speed = 2.0f;
[SerializeField]
float movSpeedX = 0.8f;
[SerializeField]
float movSpeedY = 2.4f;
bool ReachedTarget = true;
void Update()
{
if (ReachedTarget)
{
Vector2 dest = Vector2.zero;
Vector2 currentPos = transform.position;
if (Input.GetKeyUp(KeyCode.W))
{
dest = currentPos + (Vector2.up * movSpeedY);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.S))
{
dest = currentPos + (Vector2.down * movSpeedY);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.D))
{
dest = currentPos + (Vector2.right * movSpeedX);
StartCoroutine(moveTo(dest, Speed));
}
else if (Input.GetKeyUp(KeyCode.A))
{
dest = currentPos + (Vector2.left * movSpeedX);
StartCoroutine(moveTo(dest, Speed));
}
}
}
// Time to take is in seconds
IEnumerator moveTo(Vector2 TargetPosition, float TimetoTake)
{
Vector2 originalPosition = transform.position;
float Time_taken = 0f;
ReachedTarget = false;
while (Time_taken < 1)
{
Time_taken += Time.deltaTime / TimetoTake;
// Interpolating between the original and target position this basically provides your "speed"
transform.position = Vector2.Lerp(originalPosition, TargetPosition, Time_taken);
yield return null;
}
Time_taken = 0;
transform.position = TargetPosition;
ReachedTarget = true;
}
}
I can't find any documentation of CrossPlatformInputManager, and I know nothing about it. But if you need to get the event of "release a key" instead of "press the key", try this: Input.GetKeyUp.
Description
Returns true during the frame the user releases the key identified by
name.
You need to call this function from the Update function, since the
state gets reset each frame. It will not return true until the user
has pressed the key and released it again.
For the list of key identifiers see Conventional Game Input. When
dealing with input it is recommended to use Input.GetAxis and
Input.GetButton instead since it allows end-users to configure the
keys.
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour
{
void Update()
{
if (Input.GetKeyUp("space"))
{
print("Space key was released");
}
}
}
If you want to stop the rigid body, you need to reset its velocity to
zero. Or you can use
Rigidbody2D.MovePosition
to move it a certain distance.
Parameters
position The new position for the Rigidbody object.
Description
Moves the rigidbody to position.
Moves the rigidbody to the specified position by calculating the
appropriate linear velocity required to move the rigidbody to that
position during the next physics update. During the move, neither
gravity or linear drag will affect the body. This causes the object to
rapidly move from the existing position, through the world, to the
specified position.
Because this feature allows a rigidbody to be moved rapidly to the
specified position through the world, any colliders attached to the
rigidbody will react as expected i.e. they will produce collisions
and/or triggers. This also means that if the colliders produce a
collision then it will affect the rigidbody movement and potentially
stop it from reaching the specified position during the next physics
update. If the rigidbody is kinematic then any collisions won't affect
the rigidbody itself and will only affect any other dynamic colliders.
2D rigidbodies have a fixed limit on how fast they can move therefore
attempting to move large distances over short time-scales can result
in the rigidbody not reaching the specified position during the next
physics update. It is recommended that you use this for relatively
small distance movements only.
It is important to understand that the actual position change will
only occur during the next physics update therefore calling this
method repeatedly without waiting for the next physics update will
result in the last call being used. For this reason, it is recommended
that it is called during the FixedUpdate callback.
Note: MovePosition is intended for use with kinematic rigidbodies.
// Move sprite bottom left to upper right. It does not stop moving.
// The Rigidbody2D gives the position for the cube.
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour
{
public Texture2D tex;
private Vector2 velocity;
private Rigidbody2D rb2D;
private Sprite mySprite;
private SpriteRenderer sr;
void Awake()
{
sr = gameObject.AddComponent<SpriteRenderer>();
rb2D = gameObject.AddComponent<Rigidbody2D>();
}
void Start()
{
mySprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100.0f);
velocity = new Vector2(1.75f, 1.1f);
sr.color = new Color(0.9f, 0.9f, 0.0f, 1.0f);
transform.position = new Vector3(-2.0f, -2.0f, 0.0f);
sr.sprite = mySprite;
}
void FixedUpdate()
{
rb2D.MovePosition(rb2D.position + velocity * Time.fixedDeltaTime);
}
}
Both documents have an example.
Or you don't want to user keyboard but UI buttons, try this: IPointerDownHandler and IPointerUpHandler
Description
Interface to implement if you wish to receive OnPointerDown callbacks.
Detects ongoing mouse clicks until release of the mouse button. Use
IPointerUpHandler to handle the release of the mouse button.
//Attach this script to the GameObject you would like to have mouse clicks detected on
//This script outputs a message to the Console when a click is currently detected or when it is released on the GameObject with this script attached
using UnityEngine;
using UnityEngine.EventSystems;
public class Example : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
//Detect current clicks on the GameObject (the one with the script attached)
public void OnPointerDown(PointerEventData pointerEventData)
{
//Output the name of the GameObject that is being clicked
Debug.Log(name + "Game Object Click in Progress");
}
//Detect if clicks are no longer registering
public void OnPointerUp(PointerEventData pointerEventData)
{
Debug.Log(name + "No longer being clicked");
}
}
So I am making a game in unity where an object will dash in the direction (unit vector) of the player's mouse click. Based on dash speed and dash time variables I made and set in the inspector it will usually work, as in the distance dashed by the object and its velocity are usually constant. However, sometimes the dash distance of the object will be off. I attempted to troubleshoot the problem by logging the dash distance and the object's velocity and what I found was that sometimes either or both variables with be some random value for some reason I am missing. On most clicks though the variables are the same number. Here is my code:
[RequireComponent(typeof(Rigidbody2D))]
public class DashController : MonoBehaviour
{
Rigidbody2D rigidbody;
public float dashSpeed;
public float dashTime; //dash time for inspector use
float codeDashTime; //dash time for code use
bool dashing;
Vector2 direction;
Vector2 startPosition;
Vector2 endPosition;
float distance;
private void Start()
{
rigidbody = GetComponent<Rigidbody2D>();
codeDashTime = dashTime;
dashing = false;
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
//need to subtract the current postion from the target postion
direction = (Camera.main.ScreenToWorldPoint(Input.mousePosition) - this.transform.localPosition);
startPosition = this.transform.localPosition; // used to see the distance player dashes
dashing = true;
}
if (dashing)
{
Dash();
}
}
void Dash()
{
if (codeDashTime > 0)
{
rigidbody.velocity = direction.normalized * dashSpeed;
codeDashTime -= Time.deltaTime;
}
else
{
Debug.Log(rigidbody.velocity.magnitude);// used to see the velocity the player travels at
Debug.Log(direction.normalized.magnitude);
rigidbody.velocity = Vector2.zero;
endPosition = this.transform.localPosition; // used to see the distance player dashes
distance = Vector2.Distance(startPosition, endPosition);// used to see the distance player dashes
Debug.Log(distance); // used to see the distance player dashes
dashing = false;
codeDashTime = dashTime;
}
}
}
Sorry if my code is a bit jumbled. I have been moving things around a lot testing different solutions but nothing has worked. My best guess is that maybe something with the frames is messing up codeDashTime, but I am too new to unity and C# to know. Any help is appreciated, thanks.
All Physics should run on FixedUpdate and the inputs are normally used on Update, try separate them to get a better Rigidbody behaviour.
I'm following a tutorial on Unity 5 to create a simple stealth game.
I followed the instructions to create the script that controls the movement of the player. When I tested the game I noticed that the player takes a few seconds after pressing the button before moving.
It's as if before moving should await the conclusion of the rotation that is performed by Quaternion.Lerp.
Also pressing the x button should scream to attract attention and take proper animation.. It runs the sound but the animation is not done.. Was performed only once in multiple tests I did.
public class PlayerMovement : MonoBehaviour
{
public AudioClip shoutingClip; // Audio clip of the player shouting.
public float turnSmoothing = 15f; // A smoothing value for turning the player.
public float speedDampTime = 0.1f; // The damping for the speed parameter
private Animator anim; // Reference to the animator component.
private HashIDs hash; // Reference to the HashIDs.
void Awake ()
{
// Setting up the references.
anim = GetComponent<Animator>();
hash = GameObject.FindGameObjectWithTag(Tags.gameController).GetComponent<HashIDs>();
// Set the weight of the shouting layer to 1.
anim.SetLayerWeight(1, 1f);
}
void FixedUpdate ()
{
// Cache the inputs.
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
bool sneak = Input.GetButton("Sneak");
MovementManagement(h, v, sneak);
}
void Update ()
{
// Cache the attention attracting input.
bool shout = Input.GetButtonDown("Attract");
// Set the animator shouting parameter.
anim.SetBool(hash.shoutingBool, shout);
AudioManagement(shout);
}
void MovementManagement (float horizontal, float vertical, bool sneaking)
{
// Set the sneaking parameter to the sneak input.
anim.SetBool(hash.sneakingBool, sneaking);
// If there is some axis input...
if(horizontal != 0f || vertical != 0f)
{
// ... set the players rotation and set the speed parameter to 5.5f.
Rotating(horizontal, vertical);
anim.SetFloat(hash.speedFloat, 5.5f, speedDampTime, Time.deltaTime);
}
else
// Otherwise set the speed parameter to 0.
anim.SetFloat(hash.speedFloat, 0);
}
void Rotating (float horizontal, float vertical)
{
// Create a new vector of the horizontal and vertical inputs.
Vector3 targetDirection = new Vector3(horizontal, 0f, vertical);
// Create a rotation based on this new vector assuming that up is the global y axis.
Quaternion targetRotation = Quaternion.LookRotation(targetDirection, Vector3.up);
// Create a rotation that is an increment closer to the target rotation from the player's rotation.
Quaternion newRotation = Quaternion.Lerp(GetComponent<Rigidbody>().rotation, targetRotation, turnSmoothing * Time.deltaTime);
// Change the players rotation to this new rotation.
GetComponent<Rigidbody>().MoveRotation(newRotation);
}
void AudioManagement (bool shout)
{
// If the player is currently in the run state...
if(anim.GetCurrentAnimatorStateInfo(0).nameHash == hash.locomotionState)
{
// ... and if the footsteps are not playing...
if(!GetComponent<AudioSource>().isPlaying)
// ... play them.
GetComponent<AudioSource>().Play();
}
else
// Otherwise stop the footsteps.
GetComponent<AudioSource>().Stop();
// If the shout input has been pressed...
if(shout)
// ... play the shouting clip where we are.
AudioSource.PlayClipAtPoint(shoutingClip, transform.position);
}
}
I'm new in unity so I might need some more explanation. Thanks to everyone!
The first issue, delaying your player movement, may be caused by the line
anim.SetFloat(hash.speedFloat, 5.5f, speedDampTime, Time.deltaTime);
The potential issue is that you are calling Time.deltaTime, which is intended to be use inside an update() call. Your function is called inside of fixedUpdate() which means you should be using Time.fixedDeltaTime.
For your second issue, shouting, the code seems fine and the issue is likely in your animation tree. Check that the state you are in before shouting can transition to shout, and checks for the correct trigger.