Sunteți pe pagina 1din 14

4.

Scripts
4.1. Move Cameras
One function of this script is to use the cursor movement to change the position and
rotation of the camera. We want the camera to pan to the right when the mouse is
dragged to the right and tilt up when the mouse is dragged up. To do that, we need
to understand the way unity define mouse position and object rotation.

As we can see from the picture, when we want to pan the camera to the left,
we need to give a negative value to the Y (angle) while the Mouse X variable is
given the negative value. On the other hand, when we want the camera to tilt up,
we need to give a positive value to the X (angle) while the Mouse Y variable is
given negative value. The camera rotation movement script would have this
arrangement involved into it.

As for the camera position movement script, it is sufficient to give the use
values of rotation into the position coordinate. The Z-axis coordinate will, however,
be multiplied by negative so that the camera would face into the game object
(instead of facing away from it).

The script also has the function to execute raycast. Raycast will detect the
clicked object and retrieve the Tag of the object.

1. If the clicked object is tagged White, the tag will change into Red or Blue
based on whose turn it is. This tag is attached to the game blocks and the change of
tag will trigger the strokefinder script (In object array). This will also increment the
turn variable.

2. If the clicked object is tagged Poof or UnPoof, the tag will switch into the
other. This tag is attached to the poof spheres and used to deactivate one layer of
the game objects. This is so that the layers of blocks in the middle are easier to
click.

This script also manages the text that shows the number of turn on the up-
left corner of the game screen. It also manages the text that shows whose turn it is
on the upper middle game screen.

The BtnUI is a Boolean variable that refers to the pause button. BtnUI
=false means that the button has not been clicked. BtnUI = true means that the
button has been clicked and the game is in the pause state. The pause state
disables the camera rotation function and raycast function so that the player cannot
interact with the game during pause time. The mechanic of the pause script will be
explained in section 4.5 Button Manager.

The turn timer is also managed in this script. The turn timer starts when the
player turn switches. The turn timer text is not updated when the game is paused.
At the same time, while the game is paused, the pause timer will start counting.
When the game is unpaused, the turn timer will show the total turn timer (without
pause) subtracted by the total pause time.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class MoveCamera : MonoBehaviour


{
//This script is attached to the game object "main camera"
//It functions to rotate and move camera with mouse so that it would orbit the game object.
//It also functions to raycast at objects so that the object information could be retrieved and manipulated
//The variables: "int turn" and "string hitTag" would be used at other scripts.

public Transform target; //define the target object for the camera to orbit
public float distance = 10.0f; //define initial distance from camera toward target
public float xSpeed = 40.0f; //define a variable used to control camera movement speed
public float ySpeed = 40.0f;

float x = 0.0f; //define the variable for cursor-position


float y = 0.0f;

public int turn; //define the variable that counts the number of turns
public Text turnText; //define the text that would show the number of turns

public Text middleText; //define the text that would show who's turn it is

public Text turnTimer;


private float startTime;
private float timer;

public float distanceMin = 7f; //define the minimum distance from camera toward target
public float distanceMax = 15f; //define the maximum distance from camera toward target

private float temps; //a variable used to calculate the difference of time between the click until release

public string hitTag; //the string used to get the tag of raycasted object

int d = 4; //the number of blocks on each side of the cube

// Use this for initialization


void Start()
{
Vector3 angles = transform.eulerAngles; //define euler angles variables
x = angles.y; //the x value of cursor position would affect the value of y rotation of the camera
y = angles.x; //vice versa

turn = 0; //initialize turn at 0


turnText.text = "Turn: " + turn.ToString (); //initialize the text as "Turn: 0"
middleText.text = "Blue's Turn"; //initialize the first turn text for Blue's turn
middleText.color = Color.blue;

hitTag = "Red"; //initialize the first raycast hit as red, as if it was Red's turn before the game

startTime = Time.time;
}

// Update is called once per frame


void Update()
{
if (BtnUI == false) {
timer = Time.time - startTime;
timer = timer - pauseTime;
int t = (int)timer;

string hours = (t / 3600).ToString ("d2");


string minutes = (t / 60).ToString ("d2");
string seconds = (t % 60).ToString ("d2");

turnTimer.text = hours + ":" + minutes + ":" + seconds;


}

Quaternion rotation = Quaternion.Euler(y, x, 0); //convert euler angles into quarternion

distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel") * 5, distanceMin, distanceMax);


//^ calculate the distance variable while giving it limits

Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance); //distance is negated so that the camera will face ob
ject
Vector3 position = rotation * negDistance; //calculate the position

transform.rotation = rotation; //apply rotation into gameobject


transform.position = position; //apply position into gameobject

if (Input.GetMouseButton(0) && BtnUI == false){ //if "the mouse is hold"


x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f; //calculate y-rotation of the camera
y -= Input.GetAxis("Mouse Y") * ySpeed * distance * 0.02f; //calculate x-rotation of the camera
}

if (Input.GetMouseButtonDown(0) && BtnUI == false)temps = Time.time ; //if "the mouse is clicked"

if (Input.GetMouseButtonUp(0) && (Time.time - temps) < 0.2){ //if the mouse is released within under 0.2 seco
nd

Debug.Log("Mouse is down");

RaycastHit hitInfo = new RaycastHit(); //define hitInfo for raycast

bool hit = false;

if (BtnUI == false) {
hit = Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo);
//^execute raycast to mouse location with the output of hitinfo
}

if (hit){ //if "raycast hit an object"

Debug.Log("Hit " + hitInfo.transform.gameObject.name);


if (hitInfo.transform.gameObject.tag == "White") { //if "the hit object is tagged white"
Debug.Log ("It's working!");

if (turn % 2 == 0) { //if it's on the even turn


hitInfo.transform.gameObject.tag = "Blue"; //change the object tag to blue
middleText.text = "Red's Turn"; //change the text to Red's turn
middleText.color = Color.red;
startTime = Time.time - pauseTime;
}
else { //if it's on the odd turn
hitInfo.transform.gameObject.tag = "Red"; //change the object tag to red
middleText.text = "Blue's Turn"; //change the text to Blue's turn
middleText.color = Color.blue;
startTime = Time.time - pauseTime;
}

hitTag = hitInfo.transform.gameObject.tag; //update hitTag

turn++; //increment number of turn


turnText.text = "Turn: " + turn.ToString (); //update the turn text
}

//when the raycast hit one of the poof spheres


if (hitInfo.transform.gameObject.tag == "UnPoof") { //switch the tag between poof and unpoof
hitInfo.transform.gameObject.tag = "Poof";
}else
if (hitInfo.transform.gameObject.tag == "Poof") {
hitInfo.transform.gameObject.tag = "UnPoof";
}
}
else Debug.Log("No hit");

Debug.Log("Mouse is down");
}

float total = Mathf.Pow (d, 3); //calculate the total number of boxes
if (turn==total) {
middleText.text = "Game Over!"; //update middle text to gameover
middleText.color = Color.green;
}
}

public bool BtnUI=false;


float pauseTime;

public void Pause (){


if (BtnUI == true)
{
pauseTime = Time.time - pauseTime;
BtnUI = false;
}else
{
pauseTime = Time.time - pauseTime;
BtnUI = true;
}
}
}

4.2. Color Changer


This script is attached to each of the blocks. This script will read the tag of the
object and match the color of the object according to the tag.

The tag of the object is managed by the MoveCamera script. Specifically, the part
that says: {hitInfo.transform.gameObject.tag = "Blue"} and
{hitInfo.transform.gameObject.tag = "Red"}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColorScript : MonoBehaviour {

//this script is attached to the prefab of block game object


//as such, each block has this identical script
//this script functions to change the color of clicked block

public Renderer rend; //define renderer of the block, color is an aspect of rendere
r

void Start()
{
rend = GetComponent<Renderer>(); //get renderer component
}

// Update is called once per frame


void Update ()
{
if (this.CompareTag ("Blue")) { //if the object tag is "Blue"
rend.material.color = Color.blue; //change the color to blue
}

if (this.CompareTag ("Red")) { //if the object tag is "Red"


rend.material.color = Color.red; //change the color to red
}
}
}

4.3. Object Array and Stroke Finder


This script is attached to the parent object of all the blocks. It consists of the
part that would define all the blocks into a 3-dimensional array and the part that
would find a stroke. The array used in this script is called List in unity. It is a kind
of dynamic array where the size is adjustable.
The object array is used to define every block while giving it a coordinate.
For example , one of the block at the furthest corner would have the definition of
block[0][0][0] while the block next to it would have the definition of block[0][0][1].

After all of the blocks are defined into the array. The script will read the
variable hitTag from the MoveCamera script. When the hitTag variable changes,
the strokefinder function would be triggered to find and calculate the number of the
stroke that the hitTag color has achieved.

A stroke is when a line of blocks have the same color. In the picture above,
there is 1 blue straight stroke and 1 red diagonal stroke.

The strokefinder is divided into 4 parts; the first part would find all the
straight strokes that face the x-axis along with the diagonal strokes that faces the
same direction. The next 2 parts would be for the y-axis and z-axis. The last part
would find the strokes across the spatial diagonal of the cube.

The strokes from all the parts would be counted and will be displayed into the
score texts under the turn text.

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

public class ObjectArrayFTW : MonoBehaviour {


//This script is attached to the parent game object of all the boxes
//This script define all the box game objects into a 3-dimensional array
//The array variables uses a,b and c
//This script functions to find all the strokes made by the players and calculate th
e total number

int a = 0; //y axis


int b = 0; //z axis
int c = 0; //x axis

int v = 0; //convinient calculation variable

string color; //the color of recently clicked object


string oldColor; //the previous color

int colorCount; //counts the number of straight line of boxes with the same tag a
s color
int diagonalCount; //counts the number of a diagonal line of boxes
int diagonal2Count; //counts the number of the other diagonal line of boxes
int[] SpaDi = new int[4] ; //count the number for each space diagonal line of boxe
s

public int strokeCount; //count the number of total strokes made by the same pla
yer

public Text BlueText; //the text that shows how many strokes had been made by
blue player
public Text RedText; //the text that shows how many strokes had been made by
red player

public int d = 4; //4x4x4


List<List<List<GameObject>>> block = new List<List<List<GameObject>>>();
//define gameobject array

// Use this for initialization


void Start () {

strokeCount = 0;

BlueText.text = "Blue: " + strokeCount.ToString ();


RedText.text = "Red: " + strokeCount.ToString ();

//define each block into the array


for (a = 0; a < d; a++) {
block.Add (new List<List<GameObject>> ());
for (b = 0; b < d; b++) {
block [a].Add (new List<GameObject> ());

for (c = 0; c < d; c++) {


block [a][b].Add (this.gameObject.transform.GetChild (a).GetChild (b).G
etChild (c).gameObject);
}
}
}
}

// Update is called once per frame


void Update () {

//get the variable hitTag from MoveCamera script and copy it into the variable
color
GameObject kamera = GameObject.Find ("Main Camera");
MoveCamera movecamera = kamera.GetComponent<MoveCamera>();
color = movecamera.hitTag;

if (color != oldColor) //if the color changes


strokefinder (color); //execute strokefinder

oldColor = color; //update old color


}

//this function will find the strokes made by the player


void strokefinder(string color){
colorCount = 0; //initialize
strokeCount = 0; //initialize

//this part will find the straight strokes along the x axis
//it will also find the diagonal strokes on each of the "a" layer
for (a = 0; a < d; a++) {
for (b = 0; b < d; b++) {
for (c = 0; c < d; c++) {
if (block [a] [b] [c].CompareTag (color)) colorCount++;
if (b==c && block [a] [b] [c].CompareTag (color)) diagonalCount++;

v = d - c - 1;
if (b==v && block [a] [b] [c].CompareTag (color)) diagonal2Count++;
}
if (colorCount == d) strokeCount++;
colorCount = 0;
}

if (diagonalCount == d) strokeCount++;
if (diagonal2Count == d) strokeCount++;

diagonalCount = 0;
diagonal2Count = 0;
}

colorCount = 0;
diagonalCount = 0;
diagonal2Count = 0;

//y axis
for (b = 0; b < d; b++) {
for (c = 0; c < d; c++) {
for (a = 0; a < d; a++) {
if (block [a] [b] [c].CompareTag (color)) colorCount++;
if (c==a && block [a] [b] [c].CompareTag (color)) diagonalCount++;

v = d - a -1;
if (c==v && block [a] [b] [c].CompareTag (color)) diagonal2Count++;
}
if (colorCount == d) strokeCount++;
colorCount = 0;
}
if (diagonalCount == d) strokeCount++;
if (diagonal2Count == d) strokeCount++;

diagonalCount = 0;
diagonal2Count = 0;
}

colorCount = 0;
diagonalCount = 0;
diagonal2Count = 0;

//z axis
for (c = 0; c < d; c++) {
for (a = 0; a < d; a++) {
for (b = 0; b < d; b++) {
if (block [a] [b] [c].CompareTag (color)) colorCount++;
if (a==b && block [a] [b] [c].CompareTag (color)) diagonalCount++;

v = d - b - 1;
if (a==v && block [a] [b] [c].CompareTag (color)) diagonal2Count++;
}
if (colorCount == d) strokeCount++;
colorCount = 0;
}
if (diagonalCount == d) strokeCount++;
if (diagonal2Count == d) strokeCount++;

diagonalCount = 0;
diagonal2Count = 0;
}
//last 4 space diagonal
for (a=0 ;a<d ;a++){
if (block [a] [a] [a].CompareTag(color)) SpaDi[0]++;
if (block [a] [d - a - 1] [a].CompareTag(color)) SpaDi[1]++;
if (block [d - a - 1] [a] [a].CompareTag(color)) SpaDi[2]++;
if (block [d - a - 1] [d - a - 1] [a].CompareTag(color)) SpaDi[3]++;
}

for (a = 0; a < d; a++) {


if (SpaDi [a] == d) strokeCount++;
SpaDi [a] = 0;
}

colorCount = 0;
diagonalCount = 0;
diagonal2Count = 0;

if (color == "Blue")BlueText.text = "Blue: " + strokeCount.ToString ();


if (color == "Red")RedText.text = "Red: " + strokeCount.ToString ();
}
}
4.4. Poof Spheres
Because the blocks in the middle are hard to click, the poof spheres are
devised. The poof spheres can be clicked to toggle one layer of the blocks to either
appear or disappear.
Click

These spheres are initially tagged as UnPoof. By clicking on the spheres,


the tag would toggle into Poof. This is managed in the Move Camera script.

The first part of the script is to define an array of the spheres and block
layers. The plane is defined by as the child of the Parent Gameobject of all blocks.
The poof spheres are defined as the child of poof game object (where the script is
attached to).

The sphere would be paired with the layer of blocks when they have the same array
number. For example, poof[2] (the name of the sphere) is paired with plane[2] (the
name of the layer).

When the tag of poof[2] is UnPoof, the layer[2] would appear (active).
When the tag of poof[2] is Poof, the plane [2] would disappear (deactivate).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Poof : MonoBehaviour {

private float temps;


public GameObject Mom;
List<GameObject> plane = new List<GameObject>();
List<GameObject> poof = new List<GameObject>();

int a;
int d=4;

// Use this for initialization


void Start () {
Mom = GameObject.FindGameObjectWithTag ("Mom");

for (a = 0; a < d; a++) {


poof.Add (this.gameObject.transform.GetChild (a).gameObject);
plane.Add (Mom.gameObject.transform.GetChild (a).gameObject);
}
}

// Update is called once per frame


void Update () {
for (a = 0; a < d; a++) {
if (poof[a].CompareTag("Poof")){
plane [a].SetActive (false);
}

if (poof[a].CompareTag("UnPoof")){
plane [a].SetActive (true);
}
}
}

4.5 Button Manager


The Button Manager is attached to an Empty Object.

There are 2 timers attached to this script:


1. The absolute timer: The timer that counts regardless if the game is paused

2. The Timer with pause: The timer that does not count when the game is paused.

When the game is paused, the absolute timer is not affected. But the text that
would show Timer with pause does not update. At the same time, another timer
called pause time (not shown in the game) will start counting. When the game
resumes, Timer with pause is calculated by Absolute timer subtracted by Pause
time.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class ButtonManager : MonoBehaviour


{
public Text timerNoPause;
public Text timerWithPause;

private float startTime;


public float pauseTime;

public void NewGameBtn(string newGameNormal)


{
SceneManager.LoadScene(newGameNormal);
}

public GameObject MenuPanel;


public bool BtnUI=false;

public void Pause ()


{
if (BtnUI == true)
{
MenuPanel.SetActive(false);
pauseTime = Time.time - pauseTime;
BtnUI = false;
}else
{
MenuPanel.SetActive(true);
pauseTime = Time.time - pauseTime;
BtnUI = true;
}
}

public void exitgame (){


Application.Quit ();
}

void start(){
startTime = Time.time;
}

void Update(){
float ft = Time.time - startTime;
int t = (int) ft;

string hours = (t / 3600).ToString ("d2");


string minutes = (t / 60).ToString ("d2");
string seconds = (t % 60).ToString ("d2");

timerNoPause.text = "Absolute Timer = " + hours + ":" + minutes + ":" + seconds;

if (BtnUI == false) {
ft = ft - pauseTime;
t = (int) ft;

hours = (t / 3600).ToString ("d2");


minutes = (t / 60).ToString ("d2");
seconds = (t % 60).ToString ("d2");

timerWithPause.text = "Timer With Pause = " + hours + ":" + minutes + ":" + seconds;
}
}
}

S-ar putea să vă placă și