Code Problems

I was following a tutorial on making a Sonic game (https://www.youtube.com/watch?v=raIX3znrik4) when I ran into an error saying “The type or namespace name ‘IEnumerator’ could not be found (are you missing a using directive or an assembly reference?)”. I’m pretty sure I did everything right.
Here’s my code:

using UnityEngine;



public class PlayerPhysics : MonoBehaviour
{
    public Rigidbody RB;

    public LayerMask layerMask;

    public Vector3 horizontalVelocity => Vector3.ProjectOnPlane(RB.velocity, RB.transform.up);

    public Vector3 verticalVelocity => Vector3.Project(RB.velocity, RB.transform.up);

    // Update

    void Update()
    {
        if (Input.GetButtonDown("Jump"))
            Jump();
    }

    // Jump

    [SerializeField] float jumpForce;

    void Jump()
    {
        if(!ground) return;

        RB.velocity = (Vector3.up * jumpForce)
           + horizontalVelocity;
    }

    // Fixed Update

    void FixedUpdate()
    {
        Move();
        
        if(!ground)
           Gravity();

        StartCoroutine(LateFixedUpdateRoutine());
        
        IEnumerator LateFixedUpdateRoutine()
        {
            yield return new WaitForFixedUpdate();

            LateFixedUpdate();
        }
    }    
    
    // Move

    [SerializeField] float speed;

    void Move()
    {
        RB.velocity = (Vector3.right * Input.GetAxis("Horizontal") * speed) + (Vector3.forward * Input.GetAxis("Vertical") * speed)
            + verticalVelocity;
    }

    // Gravity

    [SerializeField] float gravity;

    void Gravity()
    {
        RB.velocity -= Vector3.up * gravity * Time.deltaTime;
    }

    // Late Fixed Update

    void LateFixedUpdate()
    {
        Ground();
        
        Snap();
    }
    
    // Ground

    [SerializeField] float groundDistance;

    Vector3 point;

    Vector3 normal;

    bool ground;

    void Ground()
    {
        ground = Physics.Raycast(RB.worldCenterOfMass, -RB.transform.up, out RaycastHit hit, groundDistance, layerMask, QueryTriggerInteraction.Ignore);
        
        point = ground ? hit.point : RB.transform.position;

        normal = ground ? hit.normal : Vector3.up;
    }

    // Snap

    void Snap()
    {
        RB.transform.up = normal;

        Vector3 goal = point;

        Vector3 difference = goal - RB.transform.position;

        if(RB.SweepTest(difference, out _, difference.magnitude, QueryTriggerInteraction.Ignore)) return;

        RB.transform.position = goal;
    }
}

I would appreciate if anyone wants to help.
Thanks,
Aiden

using System.Collections; at the top? iirc IEnumerators live there :thinking:

As pointed out, you are definitely missing a using directive. That will absolutely have been covered in the original tutorial.

Two steps to tutorials and / or example code:

  1. do them perfectly, to the letter (zero typos, including punctuation and capitalization)
  2. stop and understand each step to understand what is going on.

If you go past anything that you don’t understand, then you’re just mimicking what you saw without actually learning, essentially wasting your own time. It’s only two steps. Don’t skip either step.


That script also looks like it uses Rigidbody physics and yet completely bypasses the Rigidbody API by directly manipulating transforms (line 113). That’s almost always a recipe for physics mayhem, unless you really know what you are doing.

With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.

This means you may not change transform.position, transform.rotation, you may not call transform.Translate(), transform.Rotate() or other such methods, and also transform.localScale is off limits. You also cannot set rigidbody.position or rigidbody.rotation directly. These ALL bypass physics.

Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.