Plane MiniGame

From Graal Bible
Revision as of 08:20, 12 October 2021 by JimmyAkl (talk | contribs)

This minigame is similar to the Car driving minigame. However, we move a plane through obstacles.

AssetBundles: minigameplane - env

using the bundle explorer (F10):

minigameplane:

Plane.png

Obstacles.png

env:

Environment.png

Weapon: 3D/Samples/Planeminigame

findplayer("GraalID").addweapon(this.name);

//#CLIENTSIDE

function onCreated() {
  this.keepAlive = true;//SetTimer(9999);
}

function onPlayerChats() {
  if (player.chat == "plane") start();
}

public function start() {
  WARPMANAGER.Warp(19, 14 ,0.7 ,"only_ground.nw");
  new GuiWindowCtrl("PlaneMinigame") {
    profile = GuiBlueWindowProfile;
    x = 120;
    y = 0;
    width = 670;
    height = 340;
    text = "Plane Minigame";
    
    new GuiButtonCtrl("Plane") {
      profile = GuiBlueButtonProfile;
      x = 150;
      y = 90;
      width = 150;
      height = 30;
      text = "Spawnplane";
    }
      new GuiButtonCtrl("Exit") {
      profile = GuiBlueButtonProfile;
      x = 150;
      y = 120;
      width = 150;
      height = 30;
      text = "Exit";
    }
  }
}

function Plane.onAction() {
  exit();
  PLAYERMOVEMENT.Freeze();
  //Quattro3D::PlayerCamera::Instance.FreeCam = true;
  CAMERAMANGER.freecam = true;
  this.empty = GameObject::Create("empty");
  Quattro3D::PlayerCamera::Instance.transform.rotation = Quaternion::euler(0, -90, 0);
  (@"3D/Dev/AssetManager").loadAssetBundle("minigameplane");
  (@"3D/Dev/AssetManager").loadAssetBundle("env");
}

function onAssetBundleDownloaded(bundlename) {
  if (bundlename == "minigameplane") {
    this.planeprefab = GameObject::fromassetbundle("minigameplane", "assets/drivingplane/vehicles/planes/small_plane02.prefab");
    this.plane = Object::Instantiate(Type::GameObject, this.planeprefab);
    this.plane.transform.position = v3(player.x, player.z, player.y);
    this.plane.transform.localscale = v3(0.3, 0.3, 0.3);
    this.plane.transform.parent = this.empty.transform;
    
    this.RB = this.plane.AddComponent(Type::RigidBody);
    this.RB.useGravity = false;
    
    boxCollider = this.plane.AddComponent(Type::BoxCollider);
    boxCollider.size = v3(4,4,4);

    Quattro::EventManager::AddOnCollisionHandlerTo(this.plane, this.plane.layer);
    this.catcheventobject(this.plane, "onCollisionEnter", "onPlaneCollisionEnter");

    this.obstacleprefab = GameObject::fromassetbundle("minigameplane", "assets/drivingplane/vehicles/planes/obstacles 1.prefab");
    this.obstacle = Object::Instantiate(Type::GameObject, this.obstacleprefab);
    this.obstacle.transform.position = v3(player.x, player.z + 10, player.y + 20);
    this.obstacle.transform.localscale = v3(0.3, 0.3, 0.3);
    this.obstacle.transform.parent = this.empty.transform;
  }
  if (bundlename == "env") {
    this.envprefab = GameObject::fromassetbundle("env", "assets/jimmyenv2/environment.prefab");
    this.env = Object::Instantiate(Type::GameObject, this.envprefab);
    this.env.transform.position = v3(player.x, player.z + 1.5, player.y);
    this.env.transform.parent = this.empty.transform; 
  }
}

function onUpdate() {
  temp.campos = this.plane.transform.position.Add(v3(20,0,0));
  Quattro3D::PlayerCamera::Instance.transform.position = temp.campos;
  
  this.verticalInput = Input::GetAxis("Vertical");
  this.horizontalInput = Input::GetAxis("Horizontal");

  this.plane.transform.translate(Vector3::forward.Mult(Time::deltaTime * 5));

  this.plane.transform.rotate(Vector3::Right.Mult(700 * Time::deltaTime * this.verticalInput));

  this.plane.transform.rotate(Vector3::Forward.Mult(700 * Time::deltaTime * this.horizontalInput * -1));

  this.propellor = this.plane.transform.Find("Propellor");
  this.propellor.transform.rotate(Vector3::Forward.Mult(1700 * Time::deltaTime)); 
}

public function onPlaneCollisionEnter(gameobject, collision) {
  player.chat = "BOOM YOU LOST!";
  exit();
}

function Exit.onAction() {
  exit(); 
}

function exit() {
  findweapon("3D/Dev/ToolBar/Camera").cam1();
  PLAYERMOVEMENT.unfreeze();
  Object::Destroy(this.empty);
  Input::ResetInputAxes();
}

The function start() creates a UI with two buttons (Spawn Plane and Exit) allowing us to start and end the game.

Plane.onAction() (when the Spawn button is pressed) :

Calls the exit() function first to destroy GameObjects instantiated before, freezes the player using PLAYERMOVEMENT.Freeze(); ,frees the camera with Quattro3D::PlayerCamera::Instance.FreeCam = true; and loads all the assets we'll need to use.

In function onAssetBundleDownloaded(bundlename) we catch all the loaded assetbundles, we instantiate the plane, obstacles and environment. And we position them, modify their scales, add components to them and make them a child of an empty GameObject.

this.empty = GameObject::Create("empty");
this.obstacle.transform.parent = this.empty.transform;

This will help delete all the GameObjects upon deleting the empty GameObject. (Object::Destroy(this.empty);)

Now, the onUpdate() function checks for updates on every frame. SetTimer(9999) needs to be added for it to work.

This function will be responsible for moving the plane, moving the camera following the plane and turning the propeller of the plane.

First for the Camera, we want it to be looking side ways at the plane. We take the plane's position and add to the X axis:

temp.campos = this.plane.transform.position.Add(v3(20,0,0));

then we change the camera position to temp.campos;

Quattro3D::PlayerCamera::Instance.transform.position = temp.campos;

We'll also need to change the rotation of the camera since it's initially facing forward and we want it to face the plane;

Quattro3D::PlayerCamera::Instance.transform.rotation = Quaternion::euler(0, -90, 0);

Now, for the movement of the plane. It will be moving forward at a constant speed; this.plane.transform.translate(Vector3::forward.Mult(Time::deltaTime * 5));

And the Input::GetAxis() will help us move it up/down and sideways.

We also find the propellor of the plane and move it at a constant rotation speed;

this.propellor = this.plane.transform.Find("Propellor");

this.propellor.transform.rotate(Vector3::Forward.Mult(1700 * Time::deltaTime));

Finally, the function exit() switches back to the default camera: findweapon("3D/Dev/ToolBar/Camera").cam1();

unfreezes the Player, destroys the GameObjects and resets the Input Axes using: Input::ResetInputAxes();

Planeminigame gameplay.png

You can also add collision detection to the plane to turn it into an actual game.

Quattro::EventManager::AddOnCollisionHandlerTo(this.plane, this.plane.layer);
this.catcheventobject(this.plane, "onCollisionEnter", "onPlaneCollisionEnter");

and implement the function:

public function onPlaneCollisionEnter(gameobject, collision) {
  player.chat = "BOOM YOU LOST!";
  exit();
}