Weapon Sway And Bobbing Without Animations -

Поділитися
Вставка
  • Опубліковано 26 вер 2024

КОМЕНТАРІ • 111

  • @citizengoose1342
    @citizengoose1342 Рік тому +92

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public class SwayNBobScript : MonoBehaviour
    {

    public MovementScript mover;
    [Header("Sway")]
    public float step = 0.01f;
    public float maxStepDistance = 0.06f;
    Vector3 swayPos;
    [Header("Sway Rotation")]
    public float rotationStep = 4f;
    public float maxRotationStep = 5f;
    Vector3 swayEulerRot;
    public float smooth = 10f;
    float smoothRot = 12f;
    [Header("Bobbing")]
    public float speedCurve;
    float curveSin {get => Mathf.Sin(speedCurve);}
    float curveCos {get => Mathf.Cos(speedCurve);}
    public Vector3 travelLimit = Vector3.one * 0.025f;
    public Vector3 bobLimit = Vector3.one * 0.01f;
    Vector3 bobPosition;
    public float bobExaggeration;
    [Header("Bob Rotation")]
    public Vector3 multiplier;
    Vector3 bobEulerRotation;
    // Start is called before the first frame update
    void Start()
    {

    }
    // Update is called once per frame
    void Update()
    {
    GetInput();
    Sway();
    SwayRotation();
    BobOffset();
    BobRotation();
    CompositePositionRotation();
    }
    Vector2 walkInput;
    Vector2 lookInput;
    void GetInput(){
    walkInput.x = Input.GetAxis("Horizontal");
    walkInput.y = Input.GetAxis("Vertical");
    walkInput = walkInput.normalized;
    lookInput.x = Input.GetAxis("Mouse X");
    lookInput.y = Input.GetAxis("Mouse Y");
    }
    void Sway(){
    Vector3 invertLook = lookInput *-step;
    invertLook.x = Mathf.Clamp(invertLook.x, -maxStepDistance, maxStepDistance);
    invertLook.y = Mathf.Clamp(invertLook.y, -maxStepDistance, maxStepDistance);
    swayPos = invertLook;
    }
    void SwayRotation(){
    Vector2 invertLook = lookInput * -rotationStep;
    invertLook.x = Mathf.Clamp(invertLook.x, -maxRotationStep, maxRotationStep);
    invertLook.y = Mathf.Clamp(invertLook.y, -maxRotationStep, maxRotationStep);
    swayEulerRot = new Vector3(invertLook.y, invertLook.x, invertLook.x);
    }
    void CompositePositionRotation(){
    transform.localPosition = Vector3.Lerp(transform.localPosition, swayPos + bobPosition, Time.deltaTime * smooth);
    transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(swayEulerRot) * Quaternion.Euler(bobEulerRotation), Time.deltaTime * smoothRot);
    }
    void BobOffset(){
    speedCurve += Time.deltaTime * (mover.isGrounded ? (Input.GetAxis("Horizontal") + Input.GetAxis("Vertical"))*bobExaggeration : 1f) + 0.01f;
    bobPosition.x = (curveCos*bobLimit.x*(mover.isGrounded ? 1:0))-(walkInput.x * travelLimit.x);
    bobPosition.y = (curveSin*bobLimit.y)-(Input.GetAxis("Vertical") * travelLimit.y);
    bobPosition.z = -(walkInput.y * travelLimit.z);
    }
    void BobRotation(){
    bobEulerRotation.x = (walkInput != Vector2.zero ? multiplier.x * (Mathf.Sin(2*speedCurve)) : multiplier.x * (Mathf.Sin(2*speedCurve) / 2));
    bobEulerRotation.y = (walkInput != Vector2.zero ? multiplier.y * curveCos : 0);
    bobEulerRotation.z = (walkInput != Vector2.zero ? multiplier.z * curveCos * walkInput.x : 0);
    }
    }

  • @nullpointerexception1052
    @nullpointerexception1052 9 місяців тому +11

    Just posting this in case someone needs it...
    If you're having this issue with the sway function I had where your weapon disappears as soon as you press play (because your gameobject's initial position _isn't_ 0):
    1. Store the Transform's initial position (and rotation if needed). You can do this in Awake() or Start(). Let's say we stored it in a variable named *initialPos*
    2. Change this line in Sway():
    -swayPos = invertLook;-
    swayPos = invertLook + initialPos;
    For rotation:
    1. Store the Transform's initial rotation (either as Quaternion or Vector, doesn't matter). Let's say we stored it in a variable named *initialRot*
    2. Change this line in SwayRotation():
    -swayEulerRot = new Vector3(invertLook.y, invertLook.x, invertLook.x);-
    swayEulerRot = new Vector3(invertLook.y, invertLook.x, invertLook.x) + initialRot.eulerAngles;

  • @airsoftbeast11234
    @airsoftbeast11234 3 місяці тому +3

    For those with issues with bobbing looking bad, I would recommend offsetting the vertical component of the bob by half a sin wave, rather than it moving in circles which look unnatural, it will go in more of a V shape:
    bobPosition.x = (cos(speedCurve) * bobLim.x) - (walkInput.x * travel.x)
    bobPosition.y = (sin(speedCurve * 2) * bobLim.y) - (vel.y * travel.y)

  • @ironmikesims
    @ironmikesims Рік тому +8

    This is pretty much the only tutorial I can find on this type of bobbing. Trying to implement it in Unreal Engine. Got the sway working perfectly but the bobbing is driving me nuuuuts!

    • @asdfghjkl-jk6mu
      @asdfghjkl-jk6mu 3 місяці тому

      having the opposite problem in another engine. ☠

    • @ironmikesims
      @ironmikesims 3 місяці тому

      @@asdfghjkl-jk6mu check your axis. X and Y might be flipped. In UE, I ended up figuring it out but went through so many iterations that I'm not sure what I did lol. But, long story short, I remembered UE's axes are different so had to adjust accordingly.

    • @asdfghjkl-jk6mu
      @asdfghjkl-jk6mu 3 місяці тому

      @@ironmikesims nah it's not the rotation order. i had problems with mouse movement being jerky because it would register even if you accidentally moved the mouse a little bit so it looked bad. also the mouse input was not zero'ing out due to the way it's handled in the engine i'm using so i had to lerp it back to zero manually.

  • @rightsider
    @rightsider Рік тому +1

    this video was incredibly helpful and educating, thank you fr!!

  • @iiropeltonen
    @iiropeltonen 6 місяців тому +1

    Excellent code 🎉

  • @developer2
    @developer2 2 місяці тому

    To anyone with the issue of slower visual bobbing when going left or backwards (or both), you can apply the Mathf.Abs() function to the input vectors. I assume it's an issue with negative output of Input.GetAxis though it's 6 AM and i'm way too lazy to figure out an actual fix
    Still can't really figure out the issue with the faster bobbing when pressing key combinations (W+D) but i'll look at it later

  • @kingchelios
    @kingchelios Рік тому +4

    Thanks ! My controller feels finally juicy.

  • @ayushgaminghub3664
    @ayushgaminghub3664 15 днів тому

    hey i need to know does this script manipulate the object so that it simulates headbob movement but not the camera

  • @staticplays1871
    @staticplays1871 4 місяці тому +1

    How did you add a grid mesh to the ground

    • @buffatwo
      @buffatwo  4 місяці тому +1

      It's the map from the Character Movement Fundamentals pack I mention at around 1:00. That said, it's just a simple grid texture, so if you were to draw a grid and use it as the texture for a material you could easily create your own.

    • @staticplays1871
      @staticplays1871 4 місяці тому

      @@buffatwo cool.

  • @CuitoFlo
    @CuitoFlo 2 місяці тому +1

    how do i get the character movement fundamentals pack, do i have to pay to make the script work?

    • @buffatwo
      @buffatwo  2 місяці тому +1

      The pack on its own at full price is $37 in the unity asset store, but I picked up the pack as part of a humble bundle god knows how long ago. However you **DON'T** need it to make the sway and bobbing script functional. You just need to set it up to read your player's movement and looking inputs, and to place the script on the "empty" game object which holds your weapon's view model.
      I originally built this script to use with my own custom character controller for Privateer, the game I was making at the time. It doesn't rely on the character controller at all though, just reading the inputs of the player. As such, you should be able to use it with just about any first person character controller.

    • @CuitoFlo
      @CuitoFlo 2 місяці тому

      @@buffatwo thank you man, even commenting after a year on your vieo you helped me

  • @mehmetuysun3545
    @mehmetuysun3545 10 місяців тому +2

    This is perfect. Thanks for your work and sharing. Worked like a charm. But i have a question if u mind, when my WeaponHolder object is selected in the Hierarchy tab during the play mode, it looks like variables are doubling themselves (like rotationStep, maxRotationStep, stepDistance etc.) I do not know if this is something like observer effect (?:D) or there have been a bug in the editor. If i click anywhere blank on the hierarchy tab and deselect my WeaponHolder object which is script attached to it reverts back to normal. Anyone know anything about this? Thanks.

    • @zzeymisim7525
      @zzeymisim7525 10 місяців тому +1

      👏🏻👏🏻👏🏻

    • @buffatwo
      @buffatwo  10 місяців тому +1

      Not for sure, to be honest. It's not something I ever noticed when I was working with this code.

    • @mehmetuysun3545
      @mehmetuysun3545 10 місяців тому +1

      @@buffatwo thank you anyway. Great work.

  • @DaBluePie
    @DaBluePie Рік тому +2

    How do I adjust the bobbing speed to the speed of the character controller ?

    • @buffatwo
      @buffatwo  Рік тому +3

      As in linking it to the velocity the character is moving at, so a faster move speed would cause it to Bob faster?
      You’d want to include the velocity of the character in with one of the equations in the Bob Offset function. Personally I’d probably add it somewhere into the iteration of speedCurve, so both the sin and cos wave are effected. Alternatively, you could add it to the sin and cos wave separately so they are effected different amounts.
      You’d probably need to play with it a bit, it’s been a bit since I’ve touched the code for this.

    • @DaBluePie
      @DaBluePie Рік тому

      @@buffatwo thx

  • @DenisFomin
    @DenisFomin 5 місяців тому

    Reworked the input method GetInput() to take data from the angular velocities of the VR controller.
    It turned out to be fun, I will use a similar system in my game Falling Down XR.
    void GetInput()
    {
    // Getting the angular velocity of the controller
    Vector3 angularVelocity = InputBridge.Instance.GetControllerAngularVelocity(ControllerHand.Right);
    // Using the controller's angular velocity to simulate mouse movement
    // Sensitivity can be adjusted here depending on the desired sway and bob effects
    lookInput.x = angularVelocity.y; // Can multiply by a factor to adjust sensitivity
    lookInput.y = -angularVelocity.x; // Can multiply by a factor to adjust sensitivity
    // Simulating character movement
    // In VR, character movement usually depends on spatial positioning, but if needed,
    // other parameters such as the controller's acceleration can be used to determine "walking"
    Vector3 linearVelocity = InputBridge.Instance.GetControllerVelocity(ControllerHand.Right);
    walkInput.x = linearVelocity.x; // Example of using horizontal speed for movement
    walkInput.y = linearVelocity.z; // Example of using vertical speed for movement
    walkInput = walkInput.normalized; // Normalization to ensure uniform input scale
    }

  • @megabiteyt
    @megabiteyt Рік тому +4

    Hey there. when I tried implementing the sway, my camera went low for some reason. Have you encountered this?

    • @buffatwo
      @buffatwo  Рік тому

      I'm not 100% sure what you mean by "went low", however the way I've got the script set up in the video it's going change the position of whatever object the script is attached to. If I had to guess, you might've put the script on the camera or its parent, which set that object's local position to near (0,0,0).
      If you take a look at 0:57 you can see the gameobject heirarchy. "CameraRoot" is the object holding the camera at about eye level, and is what is actually turned by the player input. Inside of it is the "WeaponHolder" which is what the sway and bob script is attached to, and inside of that game object is our "Weapon" (which is actually just a scaled cube as a place holder). Since the Weapon holder is a child object, its local (0,0,0) position is the exact position of its parent.

    • @megabiteyt
      @megabiteyt Рік тому +1

      Hey, ​ @BuffaLou. What I meant by "went low" was that the camera's y position decreased. The thing it's, in my heirarchy is the exact same thing. But how did you offset your weapon from the localPosition of the cameraRoot?

    • @buffatwo
      @buffatwo  Рік тому

      Well in the tutorial I'm not worrying about changing the weapons offset, so I just place it where it looks good. Since we are moving its parent (WeaponHolder), the child object will maintain whatever local position you set within it.
      In my actual project I will spawn a view model at the local (0,0,0) then pause the scene and move it inside of its parent object to where it looks good. I'll then copy that position, exit play mode, and save it as a Vector3 variable. Then next time I enter play mode, when I go to instantiate the view model I'll set the position using the variable instead of (0,0,0).

    • @megabiteyt
      @megabiteyt Рік тому +1

      The thing is, my WeaponHolder always goes to the CameraRoot gameObject.

    • @buffatwo
      @buffatwo  Рік тому

      @@megabiteyt Gotcha, so that is your issue then. Make an empty game object inside of CameraRoot and make it your new "WeaponHolder", and put the script on it.
      That way (0,0,0) of the new WeaponHolder object is whatever position CameraRoot is currently at.

  • @neozoid7009
    @neozoid7009 Рік тому

    Super Awesome tutorial thanks . please make a tutorial on on multi aim Down sight , multiple scope , leaning and reloading weapon .👍🔫

  • @lowHP_
    @lowHP_ Рік тому +3

    Thanks for the great video,
    though there is one thing I wanna mention, about bobbing
    when you press W&A Or S&D the sin/cos waves have the same values but one with + and the other with -
    which means they will be gone because basically what is happening is
    let's say cos is 3 when I am pressing W
    And sin is -3 when I press A
    this will happen 3 + (-3) = 0
    zero is our bobbing value now
    Can you help me find a solution,
    I tried messing with the values to find where is the effector but i couldn't,
    thanks once again

    • @buffatwo
      @buffatwo  Рік тому

      Sine and Cosine should generate two different waves out of phase with eachother, even if they are fed the same input values.
      In fact, if you take the value of a sine and cosine wave and chart them as the X and Y coordinates on a graph, the result should be a point moving in a circle. en.wikipedia.org/wiki/Sine_and_cosine#Differential_equation_definition
      I don't think the issue is with your values, but more likely how you're applying them to the object you are trying to move around. You might be having them both impact the same axis, for example.

    • @lowHP_
      @lowHP_ Рік тому +1

      ​@@buffatwo Thanks for the response,
      true, but you see that area where they are kind of moving toward each other in the drawn waves,
      here bobbing gets reduced to a point where it looks like there is no bobbing,
      is there a solution to prevent that
      (sorry for the bad English but I hope you understand)

    • @buffatwo
      @buffatwo  Рік тому

      @@lowHP_ Well without looking at your code, I can't actually help you debug it. But I'm also not tech support (no offense). But again I can assure you the issue is not with the sine and cosine waves themselves.
      @GamesForNon-Gamers included this code in his own starter assets. He has it up on both Github and the Unity Asset Store so I know you can find a working version of it there: ua-cam.com/video/athMUGbD0Ic/v-deo.html

    • @lowHP_
      @lowHP_ Рік тому

      @@buffatwo ok,
      I know very well that you are not tech support my friend but it's your code so I thought telling you will make sense,
      anyway, thanks for your time

    • @williamwasd1387
      @williamwasd1387 Рік тому +2

      I fixed this by making it independent on input direction, as long as i move i want the weapon to bob the same, however i'm only using rotational bob, here is my solution. Maybe you can merge it with the positional bob.
      void BobRotation()
      {
      speedCurve += Time.deltaTime * bobSpeed + 0.01f;
      float inputMagnitude = Mathf.Sqrt((Input.GetAxis("Horizontal") * Input.GetAxis("Horizontal")) + (Input.GetAxis("Vertical") * Input.GetAxis("Vertical")));
      bobEulerRotation.x = multiplier.x * (Mathf.Sin(2 * speedCurve) / 2) * inputMagnitude;
      bobEulerRotation.y = multiplier.y * curveCos * inputMagnitude;
      bobEulerRotation.z = multiplier.z * curveCos * walkInput.x;
      }

  • @jungmin.4645
    @jungmin.4645 Рік тому +1

    How could you see the variable graph in the unity? Like 2:41

    • @buffatwo
      @buffatwo  Рік тому +1

      That wasn't done in unity, I used the Desmos online graphing calculator to show what was happening.

  • @prodbyplayboii
    @prodbyplayboii 3 місяці тому

    bobbing is changing speed when going diagonally

  • @piyushguptaji402
    @piyushguptaji402 8 місяців тому

    them font nice, what is it ? jetbrains mono ?

  • @inatesi
    @inatesi 6 місяців тому

    thank youuu!! !!!!11

  • @torss_11
    @torss_11 Рік тому +1

    everything works perfectly but when you fall a long distance the gun flyes up very high so you cant see it, is there any way to put a "cap" on how far up the gun can go?

    • @buffatwo
      @buffatwo  Рік тому

      I actually ended up catching this in the dev log I put out right after this video, but decided to kick it down the road at the time. Unfortunately, that means I never actually fixed it, because around the turn of the new year I decided I was going to drop game dev entirely and just focus on making videos.
      However, to answer your question, you'd want to clamp the value some time after you originally set it. There's a few ways you could do this, but probably inside BobOffset() I'd add a line to clamp bobPosition.y directly, since it's the only value to have the issue. Check out Mathf.Clamp in the Unity scripting docs if you aren't familiar with how it works.

    • @torss_11
      @torss_11 Рік тому +1

      @@buffatwo Thanks a lot, it works AMAZING! i just added bobPosition.y = Mathf.Clamp(bobPosition.y, -0.1f, 0.2f); at the bottom of the BobOffset().

  • @KillerKaneoss
    @KillerKaneoss 11 місяців тому +1

    hi, ive found an issue, when i walk backwards, my bobbing is very slow, and when i walk diagonally, my bobbing is very fast, any ideas why?

    • @buffatwo
      @buffatwo  11 місяців тому

      Not particularly. The best I can guess is that it’s something regarding how you’re applying your movement speed to the sine/cos wave.
      When moving diagonally, you might not be normalizing a value somewhere, leading to your diagonal vector’s magnitude being a larger value than it should be. Doing that *might* also fix your forward/backward movement too.

    • @drigozx
      @drigozx 7 місяців тому

      @@buffatwo How would you do this?

    • @buffatwo
      @buffatwo  7 місяців тому

      @@drigozx Normalization is a built-in function of unity's various vector types, if that's what you're asking for.
      docs.unity3d.com/ScriptReference/Vector3.Normalize.html

    • @drigozx
      @drigozx 6 місяців тому

      @@buffatwo Yes, i know that, however I don't know which value needs to be normalized. I can provide you with my code here:
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      public class WeaponSwaying : MonoBehaviour
      {
      public PlayerMovement mover;
      [Header("Sway")]
      public float step = 0.01f;
      public float maxStepDistance = 0.06f;
      Vector3 swayPos;
      public PlayerMovement pm;
      [Header("Sway Rotation")]
      public float rotationStep = 4f;
      public float maxRotationStep = 5f;
      Vector3 swayEulerRot;
      public float smooth = 10f;
      float smoothRot = 12f;
      [Header("Bobbing")]
      public float speedCurve;
      float curveSin {get => Mathf.Sin(speedCurve);}
      float curveCos {get => Mathf.Cos(speedCurve);}
      public Vector3 travelLimit = Vector3.one * 0.025f;
      public Vector3 bobLimit = Vector3.one * 0.01f;
      Vector3 bobPosition;
      public float bobSpeed;
      public float bobExaggeration;
      public float SprintingBobbing;
      public float WalkingBobbing;
      public float CrouchingBobbing;
      public float AimingBobbing;
      [Header("Bob Rotation")]
      public Vector3 multiplier;
      Vector3 bobEulerRotation;
      // Start is called before the first frame update
      void Start()
      {

      }
      // Update is called once per frame
      void Update()
      {
      GetInput();
      Sway();
      SwayRotation();
      BobOffset();
      BobRotation();
      CompositePositionRotation();
      }
      Vector2 walkInput;
      Vector2 lookInput;
      void GetInput(){
      walkInput.x = Input.GetAxis("Horizontal");
      walkInput.y = Input.GetAxis("Vertical");
      walkInput = walkInput.normalized;
      lookInput.x = Input.GetAxis("Mouse X");
      lookInput.y = Input.GetAxis("Mouse Y");
      }
      void Sway(){
      Vector3 invertLook = lookInput *-step;
      invertLook.x = Mathf.Clamp(invertLook.x, -maxStepDistance, maxStepDistance);
      invertLook.y = Mathf.Clamp(invertLook.y, -maxStepDistance, maxStepDistance);
      swayPos = invertLook;
      }
      void SwayRotation(){
      Vector2 invertLook = lookInput * -rotationStep;
      invertLook.x = Mathf.Clamp(invertLook.x, -maxRotationStep, maxRotationStep);
      invertLook.y = Mathf.Clamp(invertLook.y, -maxRotationStep, maxRotationStep);
      swayEulerRot = new Vector3(invertLook.y, invertLook.x, invertLook.x);
      }
      void CompositePositionRotation(){
      transform.localPosition = Vector3.Lerp(transform.localPosition, swayPos + bobPosition, Time.deltaTime * smooth);
      transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(swayEulerRot) * Quaternion.Euler(bobEulerRotation), Time.deltaTime * smoothRot);
      }
      void BobOffset(){
      speedCurve += Time.deltaTime * (mover.grounded ? (Input.GetAxis("Horizontal") + Input.GetAxis("Vertical"))*bobExaggeration : 1f) + 0.01f;
      bobPosition.x = (curveCos*bobLimit.x*(mover.grounded ? 1:0))-(walkInput.x * travelLimit.x);
      bobPosition.y = (curveSin*bobLimit.y)-(Input.GetAxis("Vertical") * travelLimit.y);
      bobPosition.z = -(walkInput.y * travelLimit.z);
      }
      void BobRotation()
      {
      speedCurve += Time.deltaTime * bobSpeed + 0.01f;
      float inputMagnitude = Mathf.Sqrt((Input.GetAxis("Horizontal") * Input.GetAxis("Horizontal")) + (Input.GetAxis("Vertical") * Input.GetAxis("Vertical")));
      bobEulerRotation.x = multiplier.x * (Mathf.Sin(2 * speedCurve) / 2) * inputMagnitude;
      bobEulerRotation.y = multiplier.y * curveCos * inputMagnitude;
      bobEulerRotation.z = multiplier.z * curveCos * walkInput.x;
      }
      }

  • @iEarth60
    @iEarth60 9 місяців тому

    Cleaner version:
    using UnityEngine;
    public class SwayNBobScript : MonoBehaviour
    {
    public PlayerMovement mover;
    [Header("Sway")]
    public float step = 0.01f;
    public float maxStepDistance = 0.06f;
    Vector3 swayPos;
    [Header("Sway Rotation")]
    public float rotationStep = 4f;
    public float maxRotationStep = 5f;
    Vector3 swayEulerRot;
    public float smooth = 10f;
    float smoothRot = 12f;
    [Header("Bobbing")]
    public float speedCurve;
    float curveSin {get => Mathf.Sin(speedCurve);}
    float curveCos {get => Mathf.Cos(speedCurve);}
    public Vector3 travelLimit = Vector3.one * 0.025f;
    public Vector3 bobLimit = Vector3.one * 0.01f;
    Vector3 bobPosition;
    public float bobExaggeration;
    [Header("Bob Rotation")]
    public Vector3 multiplier;
    Vector3 bobEulerRotation;
    void Update()
    {
    GetInput();
    Sway();
    SwayRotation();
    BobOffset();
    BobRotation();
    CompositePositionRotation();
    }
    Vector2 walkInput;
    Vector2 lookInput;
    void GetInput()
    {
    walkInput.x = Input.GetAxis("Horizontal");
    walkInput.y = Input.GetAxis("Vertical");
    walkInput = walkInput.normalized;
    lookInput.x = Input.GetAxis("Mouse X");
    lookInput.y = Input.GetAxis("Mouse Y");
    }
    void Sway()
    {
    Vector3 invertLook = lookInput *-step;
    invertLook.x = Mathf.Clamp(invertLook.x, -maxStepDistance, maxStepDistance);
    invertLook.y = Mathf.Clamp(invertLook.y, -maxStepDistance, maxStepDistance);
    swayPos = invertLook;
    }
    void SwayRotation()
    {
    Vector2 invertLook = lookInput * -rotationStep;
    invertLook.x = Mathf.Clamp(invertLook.x, -maxRotationStep, maxRotationStep);
    invertLook.y = Mathf.Clamp(invertLook.y, -maxRotationStep, maxRotationStep);
    swayEulerRot = new Vector3(invertLook.y, invertLook.x, invertLook.x);
    }
    void CompositePositionRotation()
    {
    transform.localPosition = Vector3.Lerp(transform.localPosition, swayPos + bobPosition, Time.deltaTime * smooth);
    transform.localRotation = Quaternion.Slerp(transform.localRotation, Quaternion.Euler(swayEulerRot) * Quaternion.Euler(bobEulerRotation), Time.deltaTime * smoothRot);
    }
    void BobOffset()
    {
    speedCurve += Time.deltaTime * (mover.onGround ? (Input.GetAxis("Horizontal") + Input.GetAxis("Vertical"))*bobExaggeration : 1f) + 0.01f;
    bobPosition.x = (curveCos*bobLimit.x*(mover.onGround ? 1:0))-(walkInput.x * travelLimit.x);
    bobPosition.y = (curveSin*bobLimit.y)-(Input.GetAxis("Vertical") * travelLimit.y);
    bobPosition.z = -(walkInput.y * travelLimit.z);
    }
    void BobRotation()
    {
    bobEulerRotation.x = (walkInput != Vector2.zero ? multiplier.x * (Mathf.Sin(2*speedCurve)) : multiplier.x * (Mathf.Sin(2*speedCurve) / 2));
    bobEulerRotation.y = (walkInput != Vector2.zero ? multiplier.y * curveCos : 0);
    bobEulerRotation.z = (walkInput != Vector2.zero ? multiplier.z * curveCos * walkInput.x : 0);
    }
    }

  • @MiniDuncan
    @MiniDuncan Рік тому +1

    My game doesn't have a mover script but I do have a bool for isGrounded on my playercontroller script
    I tried doing PlayerController.instance.isGrounded but it returned "object not set to an instance of an object"
    Is there anything I can try?

    • @buffatwo
      @buffatwo  Рік тому

      "Mover" is arbitrary - it's just the script that came with the scene I used for demonstration.
      If i had to guess, either "PlayerController" or "PlayerController.instance" is a null reference, and that's causing the issue.
      Try making whatever variable you're using public and assigning the reference manually via the inspector.

  • @citizen1791
    @citizen1791 Рік тому +1

    can you help with the bobbing part to not use quaternion? (godot)

    • @buffatwo
      @buffatwo  Рік тому

      I'm not familiar with how godot handles angles, since I've never used godot, but I would imagine it's some sort of Vector 3 (for a roll, pitch, and yaw angles expressed as floats). You're in luck, because I also have no clue how quaternions work on a fundamental level. What I did for this code was feed a vec 3 into Quaternion.Euler() which automatically does the conversion for me - taking that roll, pitch and yaw angle and turning it into an equivalent quaternion, which gets fed into the function.
      You'll need to do some experimenting, as I don't really do game dev any more, but what the line of code with quaternions does is spherically interpolate between the game objects current angle and the target we want to reach. The time/smoothing components of that line make it so that occurs over a few frames. The part where I multiply the two quaternions together is just the process of adding quaternions together to get the combined angle. To "add" two quaternions together, you have to multiply them. How that math works, I'm not sure, but it does.
      Your best bet for figuring out how to get that working is taking a look at Unity's Quaternion.Slerp() documentation, then trying to see if godot has an equivalent, which it probably does. docs.unity3d.com/ScriptReference/Quaternion.Slerp.html
      Sorry that I can't be much more help than that. Hope you get it figured out!

    • @citizen1791
      @citizen1791 Рік тому +1

      @@buffatwo after seeing your explanation again it finally clicked for me and i got it working, thanks! (i tried to learn quaternions and it involves 4D wtf?)

    • @buffatwo
      @buffatwo  Рік тому

      @@citizen1791 Yea quaternions are weird, which is why I made no effort to actually learn them and just use the euler conversion instead :^)

  • @MMithy
    @MMithy Рік тому +1

    does this script make it sway up when the player falls ? and how ?

    • @buffatwo
      @buffatwo  Рік тому +1

      It does, but the code as written uses a scaling factor rather than a hard upper limit. I show this off as a bug with it in Privateer Dev Log #11. I didn’t fix it, but the solution is to clamp the upper/lower limit of the value.

  • @torpedostrike8810
    @torpedostrike8810 Рік тому +1

    ill probably figure this out before a reply, but is the speed curve suppose to increase in value every frame? like will anything bad happen, like if the player goes so far away from 0,0,0

    • @buffatwo
      @buffatwo  Рік тому

      Since you would have this as a child game object of the player, it shouldn’t. Game objects inherit the position and move relative to their parent.
      The purpose of the speed curve increasing is to move the wave right-to-left and actually iterate the value. If it didn’t, we’d be stuck at a single point on the curve and nothing would actually move.

    • @torpedostrike8810
      @torpedostrike8810 Рік тому

      Thx for the quick response, the my gun/sway is on the player parent, might just be how ive setup everything with my script. But i still get the iterating motion, so i think its ag even tho it goes up.
      i do reset it back to 0 when it reaches 100 eventually

    • @torpedostrike8810
      @torpedostrike8810 Рік тому

      Hey another quick question. so if i was to add some randomess in the general circle motion/pattern i noticed, would i add that to curveSin & CurveCos?

    • @tbwentmia
      @tbwentmia 3 місяці тому

      @@torpedostrike8810 I was thinking the same thing, also its sinusoidal so surely you would reset back to 0 every 360. Anyways, ill try it out and see if it works

    • @tbwentmia
      @tbwentmia 3 місяці тому

      @@torpedostrike8810 Nevermind did some research and a reset wouldnt be necesesary if the speed curve increses every second it would take 10^30 years for it too break so we good

  • @KenHaise
    @KenHaise 8 місяців тому

    Assets\Scripts\SwayNBobScript.cs(93,47): error CS1061: 'PlayerController' does not contain a definition for 'isGrounded' and no accessible extension method 'isGrounded' accepting a first argument of type 'PlayerController' could be found (are you missing a using directive or an assembly reference?)

    • @Wiwhy
      @Wiwhy 6 місяців тому

      same

    • @XDEVROK
      @XDEVROK 5 місяців тому

      maybe u using old unity version

    • @KenHaise
      @KenHaise 4 місяці тому +1

      @@XDEVROK i was using a newer unity version than him, thats prob why, i stopped that project and swapped it to a diff engine a bit ago so

    • @XDEVROK
      @XDEVROK 4 місяці тому

      @@KenHaise good luck friend and thanks for reply 😅😅 i'm also switched to godot

    • @KenHaise
      @KenHaise 4 місяці тому +1

      @@XDEVROK i use unity still, i swapped the fps to unreal engine, and im currentyl learning java programming (a bit of a multitasker)

  • @Flyen256
    @Flyen256 6 місяців тому +1

    bad code

  • @andreicristianfigula9961
    @andreicristianfigula9961 Рік тому +1

    can you give the scripts

    • @buffatwo
      @buffatwo  Рік тому

      Sorry for the late response. I'm not actively doing game development or tutorials anymore, but a couple of others have put the code into the comments that should be close to the original code.
      Alternatively, a developer named Etra has made his own version of Unity's starter assets. He contacted me some time ago, and included this system as part of the FPS tools. Etra's Starter Assets is on the Unity asset store. An overview video can be found here: ua-cam.com/video/5Yb4oaFpZ04/v-deo.html

  • @LoganOxford-p5r
    @LoganOxford-p5r Рік тому +2

    The bobbing doesnt work.

    • @buffatwo
      @buffatwo  Рік тому +1

      What seems to be the issue? Is it popping up any errors?

    • @notChocoMilk
      @notChocoMilk 7 місяців тому +3

      @@buffatwo *”The bobbing doesnt work.”*

  • @Alik-Green
    @Alik-Green Рік тому +1

    You sound like an ai voice. It isn't an AI voice is it?

    • @buffatwo
      @buffatwo  Рік тому

      No, it's my real voice. Just for most of these videos I read from a script and do multiple takes to make sure it sounds good.

  • @neozoid7009
    @neozoid7009 Рік тому

    what if my transform.localRotation is a vector3 ?? I am using a parent constraint so i have to use the ParentConstraint.getRotationOffset . please help !

  • @TheGuyWithTheLemon
    @TheGuyWithTheLemon Рік тому +4

    Great video! Was able to implement similar for my game and it's working great. I also added some FallOffset and FallRotation for when player jumps/is falling following similar method. One thing I did notice with the code is that the + 0.01f on the speed curve makes the bobbing frame-rate-dependant. So at higher frame rates, the bobbing was happening faster than at lower ones. To fix this I just removed the +0.01f. I also added and IdleMultiplier so the bob plays at a reduced rate when move input magnitude is 0. Thanks!

    • @bubunski-jd9qx
      @bubunski-jd9qx Рік тому +1

      How did you do this?

    • @MMithy
      @MMithy Рік тому +1

      can you actually explain how you made the fall sway thing ?

    • @TheGuyWithTheLemon
      @TheGuyWithTheLemon Рік тому +1

      ​@@MMithy Hey sure. I just followed the format for the Sway and Bob and made two new methods FallOffset and FallRotation. Just like the other methods, these just set variables for the fallPosition (Vector3) and fallEulerRot (Vector3). In my case i just based them off of the players current y velocity.
      FallOffset() looks like this:
      fallPosition.y = - (_currentVelocity.Value.y * _travelLimitFall.y);
      FallRotation() looks like this:
      fallEulerRot.x = (_currentVelocity.Value.y * _fallMultiplier);
      And with that, my CompositePositionRotation() looks like this:
      // Position
      transform.localPosition =
      Vector3.Lerp(transform.localPosition,
      originalPosition + swayPos + bobPosition + fallPosition,
      Time.deltaTime * smooth);

      // Limit Position
      if (Vector3.SqrMagnitude(transform.localPosition - originalPosition) > Mathf.Pow(_positionOffsetLimit, 2))
      {
      transform.localPosition = originalPosition +
      (transform.localPosition - originalPosition).normalized *
      _positionOffsetLimit;
      }

      // Rotation
      transform.localRotation =
      Quaternion.Slerp(transform.localRotation,
      Quaternion.Euler(swayEulerRot) * Quaternion.Euler(bobEulerRot) * Quaternion.Euler(fallEulerRot),
      Time.deltaTime * smoothRot);

      // Limit Rotation X
      var currentRotX = transform.localRotation.eulerAngles.x;
      var originalRotX = originalRotation.eulerAngles.x;
      var deltaAngle = Mathf.DeltaAngle(originalRotX, currentRotX);
      if (Mathf.Abs(deltaAngle) > _rotationAngleLimitX)
      {
      if (deltaAngle > 0)
      transform.localRotation = Quaternion.Euler(currentRotX - deltaAngle + _rotationAngleLimitX,
      transform.localRotation.eulerAngles.y,
      transform.localRotation.eulerAngles.z);
      else
      transform.localRotation = Quaternion.Euler(currentRotX - deltaAngle - _rotationAngleLimitX,
      transform.localRotation.eulerAngles.y,
      transform.localRotation.eulerAngles.z);
      }
      Hope this helps!

    • @MMithy
      @MMithy Рік тому

      @@TheGuyWithTheLemon Thanks!! I'll try this as soon as I get home :)

    • @MMithy
      @MMithy Рік тому

      @@TheGuyWithTheLemon may I ask what exactly is _rotationAngleLimitX and originalRotation and _fallMultiplier ?

  • @inocug341
    @inocug341 Рік тому +2

    Weapon sway gets difficult with hands. In my game the gun model gets instantiated in the hand model, so I can't just add rotation to the gun, as I have to make my hands move with it. Not sure if there's a way to create sway with animations or use some other way

    • @buffatwo
      @buffatwo  Рік тому +1

      Ah actually you just brought up something I didn't even mention in the video.
      If you go to 0:57 you can see on the left there is an object called "WeaponHolder", which is the actual object we are moving/rotating with this script. The cube I'm using as my gun is inside of it, and it is moved to a position that makes sense for the camera. The default position/rotation of WeaponHolder is the same as the camera, but any objects within it is slightly offset to a position that feels right. As such I'm not directly rotating/moving the view model, but instead its parent game object.
      When you go to instantiate your arms/gun, you would do so inside the object with this script. Then directly after instantiating it inside WeaponHolder, you change your view model's local position to whatever offset you want. The scriptable objects for my weapons contain a Vector3 which I use to store that information.