0
\$\begingroup\$

I'm currently making a prototype for a college project in Unity. The game is a 2.5D platformer, though I've incorporated a script for the camera from a 2D platformer so the camera moves ahead of the player. Unfortunately, because my character only faces left and right and doesn't rotate, the camera doesn't move ahead to the left, which will make it difficult for the player to see ahead if they go back to the left. I'm not sure what or how I would tackle the issue in a script. These are the camera and player controller scripts I have at the moment:

CameraController:

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

public class CameraController : MonoBehaviour
{
    [SerializeField] GameObject player = null;
    [SerializeField] [Range(0.1f, 3f)] float followAhead = 2f;
    [SerializeField] [Range(0.1f, 3f)] float smoothing = 1f;

    const float m_minY = 2f;
    Vector3 targetPosition;
    Vector3 cameraOffset;

    void Start()
    {
        cameraOffset = transform.position - player.transform.position;
    }

    private void Update()
    {
        targetPosition = (player.transform.position + (player.transform.forward * followAhead)) + cameraOffset;
        targetPosition.y = Mathf.Min(targetPosition.y, m_minY);
        transform.position = Vector3.Lerp(transform.position, targetPosition, smoothing * Time.deltaTime);
    }
}

PlayerController:

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

public class PlayerController : MonoBehaviour
{
    public Animator anim;
    public float moveSpeed;
    public float jumpForce;
    public bool jumped;
    public float gravityScale;
    public float knockBackForce;
    public float knockBackTime;
    public float invincibilityLength;

    private float jumpDelay;
    private Vector3 moveDirection;
    private float knockBackCounter;
    private float invincibilityCounter;
    private CharacterController controller;

    void Start()
    {
        Cursor.visible = false;
        controller = GetComponent<CharacterController>();
        /*jumped = false;
        if(jumpDelay <= 0)
        {
            jumpDelay = 5;
        }*/
    }

    void Update()
    {
        if (knockBackCounter <= 0)
        {
            float moveHorizontal = Input.GetAxis("Horizontal");
            moveDirection = new Vector3(moveHorizontal * moveSpeed, moveDirection.y);

            if (moveHorizontal > 0)
            {
                transform.eulerAngles = new Vector3(0, 90);
            }
            else if (moveHorizontal < 0)
            {
                transform.eulerAngles = new Vector3(0, -100);
            }

            if (controller.isGrounded)
            {
                moveDirection.y = -1f;
                if (Input.GetKey(KeyCode.KeypadPlus))
                {
                    moveDirection.y = jumpForce;
                    jumped = true;
                    //StartCoroutine(SpamBlockco());
                }
                else if(!Input.GetKey(KeyCode.KeypadPlus))
                {
                    jumped = false;
                }
            }
        }
        else
        {
            knockBackCounter -= Time.deltaTime;
        }

        moveDirection.y = moveDirection.y + (Physics.gravity.y * gravityScale * Time.deltaTime);
        controller.Move(moveDirection * Time.deltaTime);

        anim.SetBool("isGrounded", controller.isGrounded);
        anim.SetFloat("Speed", Mathf.Abs(Input.GetAxis("Horizontal")));

    }

    public void Knockback(Vector3 direction)
    {
        knockBackCounter = knockBackTime;

        moveDirection = direction * knockBackForce;
        moveDirection.y = knockBackForce;
    }

    /*public IEnumerator SpamBlockco()
    {
        if (moveDirection.y == jumpForce)
        {
            yield return new WaitForSeconds(jumpDelay);
        }
        yield return null;
        jumped = false;
    }*/
}

There are two ways I'd like for it to work - either when the player presses left/right, the character instantly rotates in the desired direction and move forwards, or the player presses left/right, the character turns, and then the player has to press left/right for the character to move.

\$\endgroup\$
0
\$\begingroup\$

Add something like this to your player script:

public Vector3 GetTravelDirection() {
    return moveDirection.normalized;
}

Then use that instead of the player.transform.forward in your camera script:

smoothedForward = Vector3.MoveTowards(
                     smoothedForward,
                     playerController.GetTravelDirection(),
                     2f * Time.deltaTime);

targetPosition = (player.transform.position + (smoothedForward * followAhead)) + cameraOffset;

Here I'm assuming you've created appropriate member variables for smoothedForward and playerController.

\$\endgroup\$
  • \$\begingroup\$ Okay, I've tried that, but it causes the camera to zoom into the scene and go through the platform and background. I should note that I have the camera set to Orthographic if that has any bearing at all. \$\endgroup\$ – DustyShinigami Apr 22 at 18:19
  • \$\begingroup\$ Sounds like you should output the value you're getting from GetTravelDirection to verify it's giving you something sensible. \$\endgroup\$ – DMGregory Apr 22 at 18:50
  • \$\begingroup\$ I don't follow. \$\endgroup\$ – DustyShinigami Apr 22 at 18:52
  • \$\begingroup\$ Then you'll have to wait until I can reproduce the issue you're describing. \$\endgroup\$ – DMGregory Apr 22 at 18:54
  • \$\begingroup\$ I could try sending you the project files via my GitHub link...? \$\endgroup\$ – DustyShinigami Apr 22 at 19:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.