0
\$\begingroup\$

I am trying to make a game like Mario Party in Unity. I want the camera to automatically change between players after each turn.

I don't have a lot of experience in C#, and I totally would learn about it myself and figure out to solve it through my own acquired knowledge (which is what I'm going to spend my summer vacation doing), but I have to deliver a prototype before May.

I have followed some tutorials on how to make a game and tried to solve the problem on my own. I tried to solve it by copying some code and editing it with what I've learned, but it didn't work.

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

// Attached to Main Camera
public class CameraController : MonoBehaviour {
// Set manually in inspector
public GameObject[] players;
public float movementSpeed = 1.0f;
public float rotationSpeed = 1.0f;

StateManager theStateManager;
bool isAnimating = false;

private int currentPlayer;
private float startTime;
private float distanceToPlayer;
private Vector3 startPosition;
private Quaternion startOrientation;

//Use this for initialization
void start()
{
    theStateManager = GameObject.FindObjectOfType<StateManager> ();
    currentPlayer = 0;
    ResetCamera ();
}

//Update is called once per frame
void Update()
{
    float distanceCovered;
    float rotationCovered;
    float fractionTraveled;

    if (isAnimating == false) 
    {
        return;
    }

    // switch to previous
    if (isAnimating == true)
    {
        if (currentPlayer == 0)
            currentPlayer = players.Length - 1;
        else
            currentPlayer++;
        ResetCamera ();
    }

    // Keep moving camera
    if (transform.position != players [currentPlayer].transform.position) {
        distanceCovered = (Time.time - startTime) * movementSpeed;
        fractionTraveled = distanceCovered / distanceToPlayer;
        rotationCovered = (Time.time - startTime) * rotationSpeed;
        // Lerp to players position
        transform.position = Vector3.Lerp (
            startPosition, players [currentPlayer].transform.position, rotationCovered);
        // Stop moving camera
    } 
    else 
    {
        // Match orientation
        if (transform.rotation != players[currentPlayer].transform.rotation)
            transform.rotation = players[currentPlayer].transform.rotation;

        // Set parent transform to current player
        transform.parent = players[currentPlayer].transform;
    }

    if (theStateManager.IsDoneAnimating == true) 
    {
        isAnimating = false;
        return;
    }

    if (theStateManager.IsDoneAnimating == false) 
    {
        isAnimating = true;
    }

    isAnimating = false;
}
void ResetCamera()
{
    transform.parent = null;
    startTime = Time.time;
    startPosition = transform.position;
    startOrientation = transform.rotation;
    distanceToPlayer = Vector3.Distance (transform.position, players[currentPlayer].transform.position);
  }
}

The StateManager is a piece of code that switches the players' turns. The gameplay works thus far.

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

public class StateManager : MonoBehaviour {

// Use this for initialization
void Start () {

}

public int NumberofPlayers = 4;
public int CurrentPlayerId = 0;

public int Dicetotal;

public bool IsDoneRolling = false;
public bool IsDoneClicking = false;
public bool IsDoneAnimating = false;

public GameObject NoLegalMovesPopup;

public void Newturn () {
    // This is the start of a player's turn.
    // We don have roll for them yet.
    IsDoneRolling = false;
    IsDoneClicking = false;
    IsDoneAnimating = false;

    CurrentPlayerId = (CurrentPlayerId + 1) % NumberofPlayers;
}


// Update is called once per frame
void Update () {

    // Is the turn done?
    if (IsDoneRolling && IsDoneClicking && IsDoneAnimating) 
    {
        Debug.Log ("Turn is done!");
        Newturn ();
    }

}

public void CheckLegalMoves()
{
    // If we rolled a zero, then we clearly have no legal moves.
    if (Dicetotal == 0) 
    {
        StartCoroutine ( NoLegalMoveCoroutine() );
        return;
    }

    // Loop through all of a player's stones.
    // Now I know everyone only has one stone, but just to be sure that
    // I don miss a part of the code. Besides, being extra secure never hurt anyone
    PlayerStone[] pss = GameObject.FindObjectsOfType<PlayerStone> ();
    bool hasLegalMove = false; 
    foreach (PlayerStone ps in pss) 
    {
        if (ps.PlayerId == CurrentPlayerId) 
        {

            if (ps.CanLegallyMoveAhead (Dicetotal)) 
            {
                // TODO: Highlight tiles that are legal move spaces
                hasLegalMove = true;
            }
        }
    }

    // If no legal moves are possible, wait a sec then move to next player (and give a message)
    if(hasLegalMove == false)
    {
        StartCoroutine ( NoLegalMoveCoroutine() );
        return;
    }
}

IEnumerator NoLegalMoveCoroutine()
{
    // Display message
    NoLegalMovesPopup.SetActive (true);
    // Wait 1 second
    yield return new  WaitForSeconds(1f); 

    NoLegalMovesPopup.SetActive (false);

    Newturn ();
}

}
\$\endgroup\$
  • 1
    \$\begingroup\$ "but it didn't work" is never enough information to diagnose and solve the precise problem. What specifically happened? How did that outcome differ from what you want? \$\endgroup\$ – DMGregory Mar 20 at 16:54
  • \$\begingroup\$ @DMGregory Indeed. I discovered the debug funtion and saw the code kept looping. I fixed that, but the camera started doing weird stuff. I scrapped the code for now and I'm going to try a new piece of code \$\endgroup\$ – S.B. Mar 21 at 15:50
2
\$\begingroup\$

Looks like you already store the players GameObjects in your CameraController, so you could quite easily get their position and set the camera's position to that.

I wouldn't be setting the camera's transform to be a child of your current player though. Just have the camera position update every time the state changes to the currently selected player position, with a preferred offset, perhaps in your NewTurn() method?

\$\endgroup\$
  • \$\begingroup\$ You can also have several cameras and just swap which one is the main camera through Camera api. This has the advantage of in the future if you want to replay the view of a player you weren't currently watching, you can. The unity standard assets have a few cameras with great examples of very basic camera movement. Worth taking a look. \$\endgroup\$ – gjh33 Mar 20 at 20:34
  • \$\begingroup\$ I agree @gjh33 ! This would also be an excellent way to get some extra functionality such as showing your current player a map/overview of the whole board or where other specific players are on it. \$\endgroup\$ – AnarchyFox Mar 21 at 10:53

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.