Getting Started Examples: Difference between revisions

From Graal Bible
(Created page with "In this section you will need to have both the '''Graal3D Client''' and '''RC''' downloaded. You will also need an authorized account to be able to login to the server. #Downl...")
 
No edit summary
 
(16 intermediate revisions by the same user not shown)
Line 1: Line 1:
In this section you will need to have both the '''Graal3D Client''' and '''RC''' downloaded. You will also need an authorized account to be able to login to the server.
Here are a few examples for beginners wanting to get into Graal3D. You will need to have both the '''Worlds Client''' and '''RC''' downloaded. You will also need an authorized account to be able to login to the server.
#Download the build compressed file, uncompress it and run the Build application.
#Download the build compressed file, uncompress it and run the Build application.
#Login with your GraalID and password, a window will open containing Worlds and Account info.
#Login with your GraalID and password, a window will open containing Worlds and Account info.
Line 5: Line 5:




Once logged in, you're required to know how to use the tools that allow you to warp to different levels, debug your code... Unity tools are also available as well.  
 
Once logged in, you're required to know how to use the tools that allow you to warp to different levels, debug your code... Unity tools are also available as well.


An explanation of all the tools is available here: [[Tools]]  
An explanation of all the tools is available here: [[Tools]]  
===Building a Wall Example - ''Creating prefabs and instantiating them''===
===Building a Wall Example - ''Creating prefabs and instantiating them''===
This example is found in the Unity Manual. We will build a wall using primitive type Cubes as Gameobjects. It will be demonstrated using Unity C# and on Graal3D using graalscript.
This example is found in the Unity Manual; We will build a wall using primitive type Cubes as Gameobjects. It will be demonstrated using Unity C# and on Graal3D using Graalscript.
====Using Unity====
====Using Unity====
Open the Unity editor with a new project.
Open the Unity editor with a new project.
Line 15: Line 16:
'''Step1: Creating an empty Gameobject to hold our Script'''
'''Step1: Creating an empty Gameobject to hold our Script'''


To your scene add an empty Gameobject. To do that, right click in the Hierarchy Section and click on Create Empty, place the Gameobject in front of the camera (this Gameobject will hold our script to build a wall)
To your scene add an empty Gameobject. To do that, right click in the Hierarchy Section (on the left) and click on '''Create Empty''', place the created Gameobject in the scene in front of the camera.
 
This Gameobject will hold our script to build a wall.
 
[[File:1.png|frameless]]


'''Step2: Creating a Prefab'''
'''Step2: Creating a Prefab'''


In the same way add a Cube Gameobject to the Hierarchy (right click -> 3D Object -> Cube).
In the same way add a Cube Gameobject to the Hierarchy (right click in Hierarchy -> 3D Object -> Cube).


Now drag the Cube from the Hierarchy to the Assets Section to create a prefab (will serve as a template to instantiate cubes). Rename the Cube to block (right click on the prefab -> rename).
Now drag the Cube from the Hierarchy to the Assets Section to create a prefab (it will serve as a template to instantiate cubes). Rename the Cube to block (right click on the prefab -> rename).
 
[[File:2.png|frameless|349x349px]]


'''Step3: Running the script'''
'''Step3: Running the script'''
Line 27: Line 34:
Now to the empty Gameobject we’ll need to add the script that builds a wall.
Now to the empty Gameobject we’ll need to add the script that builds a wall.


Press on the GameObject in the Hierarchy, this will show its details in the Inspector Section (on the right). Press on Add Component and search for “script” to add a new script.
Press on the Gameobject in the Hierarchy, all its details will pop up in the Inspector Section (on the right). Press on Add Component and search for “script” to add a new script.
 
[[File:3.png|frameless]]


To modify the script, open it in your IDE and copy the C# script below.
To modify the script, open it in your IDE and copy the C# script below.


'''Note:''' Make sure you name the public class the same name as your script file.
'''Note:''' Make sure you name the public class the same name as your script file.
{| class="wikitable"
using System.Collections;
|using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
 
public class wall: MonoBehaviour {
using UnityEngine;
  public GameObject block;
 
  public int width = 10;
public class wall: MonoBehaviour
  public int height = 4;
  void Start(){
    for (int y = 0; y < height; ++y) {
      for (int x = 0; x < width; ++x) {
        Instantiate(block, new Vector3(x, y, 0), Quaternion.identity);
      }
    }
  }
}
''Building a Wall - C# Script''


{
Finally, you’ll need to add the block prefab that we’ve created earlier to script component (to replace the public Gameobject variable “block” in the script).


   public GameObject block;
To do that, drag it from the assets folder to the script component.


   public int width = 10;
[[File:Prefab.png|frameless]]


   public int height = 4;
   void Start()
   {
       for (int y = 0; y < height; ++y)
       {
           for (int x = 0; x < width; ++x)
           {
               Instantiate(block, new Vector3(x, y, 0), Quaternion.identity);
           }
       }
   }
}
|}''Building a Wall - C# Script''
Finally, you’ll need to add the block prefab that we’ve created earlier to script component (to replace the public Gameobject variable “block” in the script) (Fig.3)
[[File:1.png|frameless|485x485px]][[File:2.png|frameless|349x349px]][[File:3.png|frameless]]
''Step1                                        Step2                                                                     Step3''




After having completed all the steps above, you should be able to start your scene, it will run all the scripts of the Gameobjects... et Voilà! A Wall![[File:WallOnUnity.png|frameless|671x671px]]
After having completed all the steps above, you should be able to start your scene, it will run all the scripts of the Gameobjects... et Voilà! A Wall![[File:WallOnUnity.png|frameless|671x671px]]


''Wall with 10 Columns 4 Rows''                                           
''Wall with 10 Columns and 4 Rows''                                           


'''Explanation:'''
'''Explanation:'''


A script needs to implement a class that extends the built-in class '''MonoBehavior'''.
A script needs to implement a class that extends the built-in class '''MonoBehavior'''.
{| class="wikitable"
|public class wall: MonoBehaviour { }
|}The '''Start''' function is where you instantiate your Gameobjects.


The '''Start''' function is where you instantiate your Gameobjects.
The '''Update''' function is where the gameplay updates happen (Gameobject movement, triggering actions, taking user input...). It is similar to the onTimeOut / onMouseDown / onKeyPressed... functions in Graalscript.
 
The '''Update''' function is where the gameplay updates happen (Gameobject movement, triggering actions, taking user input...). It is similar to the onTimeOut / onMouseDown / onKeyPressed... functions in graalscript.


'''Important Note:'''
'''Important Note:'''


[[File:Coordinates.png|frameless]]
[[File:Coordinates.png|frameless]]




Line 105: Line 95:
{| class="wikitable"
{| class="wikitable"
|public static Object Instantiate(Object original, Vector3 position, Quaternion rotation);
|public static Object Instantiate(Object original, Vector3 position, Quaternion rotation);
|}We replace the Object with our block, the position with our desired position and the rotation with
|}In the example, the Object is the block and the rotation is
 
{| class="wikitable"
Quaternion.identity to indicate 0 rotation.
|Quaternion.identity
|}
to indicate 0 rotation.


'''Quaternions:'''
'''Quaternions:'''
Line 113: Line 105:
Quaternions are used to represent rotations. The most used Quaternion functions: Quaternion.LookRotation, Quaternion.Angle, Quaternion.Euler, Quaternion.Slerp, Quaternion.FromToRotation, and Quaternion.identity.
Quaternions are used to represent rotations. The most used Quaternion functions: Quaternion.LookRotation, Quaternion.Angle, Quaternion.Euler, Quaternion.Slerp, Quaternion.FromToRotation, and Quaternion.identity.


'''Another Method:'''
'''Another Way:'''


For primitive types there’s no need to actually create a prefab since they are recognized by Unity. We could have skipped step 2 where we create the prefab and modified our code to this:
For primitive types there’s no need to actually create a prefab since they are recognized by Unity. We could have skipped step 2 where we create the prefab and modified our code to this:
{| class="wikitable"
using System.Collections;
|using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
 
public class wall: MonoBehaviour {
using UnityEngine;
  public int width = 10;
 
  public int height = 4;
public class wall: MonoBehaviour
  void Start() {
 
    for (int y = 0; y < height; ++y) {
{
      for (int x = 0; x < width; ++x) {
 
        GameObject.CreatePrimitive(PrimitiveType.Cube).transform.position = new Vector3(x, y, 0);
    public int width = 10;
      }
 
    }
    public int height = 4;
  }
 
}
    void Start()
''Building a Wall - C# Script''
 
    {
 
        for (int y = 0; y < height; ++y)
 
        {
 
            for (int x = 0; x < width; ++x)
 
            {
 
                GameObject.CreatePrimitive(PrimitiveType.Cube).transform.position = new Vector3(x, y, 0);
 
            }
 
        }
 
    }
 
}
|}''Building a Wall - C# Script''
====Using Graal3D====
====Using Graal3D====
We are going to mimic the second C# script since it would be useless to upload a Cube prefab to the server, when we can simply instantiate them using PrimitiveType.
We are going to mimic the second C# script since it would be useless to upload a Cube prefab to the server, when we can simply instantiate them using PrimitiveType.


The same script above will look like this in GraalScript:
The same script above will look like this in GraalScript: ('''''Weapon:''''' ''3D/Samples/Examples/BuildingWall'')
{| class="wikitable"
findplayer("GraalID").addweapon(this.name);
|findplayer("GraalID").addweapon(this.name);
//#CLIENTSIDE
//#CLIENTSIDE
function onCreated() {
 
  this.width = 10;
function onCreated(){
  this.height = 4;
 
  for (temp.y = 0; temp.y < this.height; ++temp.y) {
  this.width = 10;
    for (temp.x = 0; temp.x < this.width; ++temp.x) {
 
      GameObject::CreatePrimitive(PrimitiveType::Cube).transform.position = v3(player.x - 5 + temp.x, temp.y, player.y + 1);
  this.height = 4;
    }
 
  }
  for (temp.y = 0; temp.y < this.height; ++temp.y) {
}
 
''Building a Wall - Graal Script''
    for (temp.x = 0; temp.x < this.width; ++temp.x) {
 
      GameObject::CreatePrimitive(PrimitiveType::Cube).transform.position = Vector3::create(player.x - 5 + temp.x, temp.y, player.y + 1);
 
    }
 
  }
 
}
|}''Building a Wall - Graal Script''


The two codes are almost the same except for:
The two codes are almost the same except for:
Line 183: Line 144:
*The “ . ” for methods is replaced by “:: ”
*The “ . ” for methods is replaced by “:: ”
'''Function format:''' Unity C#: '''''Type.method''''' => Graal Script: '''''Type::Method'''''
'''Function format:''' Unity C#: '''''Type.method''''' => Graal Script: '''''Type::Method'''''
*'''''Vector3::Create(x,y,z)''''' replaces '''new''' '''''Vector3(x,y,z)'''''
*'''''v3(x,y,z)''''' replaces '''new''' '''''Vector3(x,y,z)'''''
*The Gameobject is instantiated close to the player using (player.x and player.y)
*The Gameobject is instantiated close to the player using (player.x and player.y)
[[File:Wall.png|frameless|695x695px]]
[[File:Wall.png|frameless|695x695px]]


''Wall with 10 Columns 4 Rows''
''Wall with 10 Columns and 4 Rows''
===Circle Formation Example - Using Rotation and Mathf functions===
===Circle Formation Example - Using Rotation and Mathf functions===
This example is similar to the one above, we’ll instantiate the Cubes in a circular shape with rotation so that they all point towards the player.
This example is similar to the one above, we’ll instantiate the Cubes in a circular shape with rotation so that they all point towards the player.
====Using Unity====
====Using Unity====
Just like in the previous example; create a new script file named “CircleFormation”, open it in you editor and copy paste this code:
Just like in the previous example; create a new script file named “CircleFormation”, open it in you editor and copy paste this code:
{| class="wikitable"
using UnityEngine;
|using UnityEngine;
public class CircleFormation: MonoBehaviour {
public class CircleFormation: MonoBehaviour
  public GameObject prefab;
 
  public int numberOfObjects = 20;
{
  public float radius = 5f;
 
  void Start() {
  // Instantiates prefabs in a circle formation
    for (int i = 0; i < numberOfObjects; i++) {
 
      float angle = i * Mathf.PI * 2 / numberOfObjects;
  public GameObject prefab;
      float x = Mathf.Cos(angle) * radius;
 
      float z = Mathf.Sin(angle) * radius;
  public int numberOfObjects = 20;
      Vector3 pos = transform.position + new Vector3(x, 0, z);
 
      float angleDegrees = -angle*Mathf.Rad2Deg;
  public float radius = 5f;
      Quaternion rot = Quaternion.Euler(0, angleDegrees, 0);
 
      Instantiate(prefab, pos, rot);
  void Start()
    }
 
  }
  {
}
 
''Circle Formation - C# Script''
      for (int i = 0; i < numberOfObjects; i++)
 
      {
 
          float angle = i * Mathf.PI * 2 / numberOfObjects;
 
          float x = Mathf.Cos(angle) * radius;
 
          float z = Mathf.Sin(angle) * radius;
 
          Vector3 pos = transform.position + new Vector3(x, 0, z);
 
          float angleDegrees = -angle*Mathf.Rad2Deg;
 
          Quaternion rot = Quaternion.Euler(0, angleDegrees, 0);
 
          Instantiate(prefab, pos, rot);
 
      }
 
  }
 
}
|}''Circle Formation - C# Script''


Create an empty Gameobject in the Hierarchy, add the script to it (as a component).
Create an empty Gameobject in the Hierarchy, add the script to it (as a component).
Line 245: Line 182:
'''Explanation:'''
'''Explanation:'''


In this example we use the Mathf collection, a struct containing all the static math methods.
In this example we use the '''Mathf''' collection, a struct containing all the static math methods.


(<nowiki>https://docs.unity3d.com/ScriptReference/Mathf.html</nowiki>) for more methods.
<u>https://docs.unity3d.com/ScriptReference/Mathf.html</u> for all the methods.


We also use the Quaternion.Euler to rotate the cubes. You can rotate around whatever axis you want, in our example Quaternion.Euler(0, angleDegress, 0) rotates the cubes around the y axis.
We also use the '''''Quaternion.Euler''''' to rotate the cubes. You can rotate around whatever axis you want, in our example '''''Quaternion.Euler(0, angleDegress, 0)''''' rotates the cubes around the y axis.


'''Another Method:'''
'''Another Way:'''


Just like before we could’ve just used GameObject.CreatePrimitive(PrimitiveType.Cube) to create the cubes and then change the transform.position and the transform.rotation.
Just like before we could’ve just used '''''GameObject.CreatePrimitive(PrimitiveType.Cube)''''' to create the cubes and then change the transform.position and the transform.rotation.
====Using Graal3D====
====Using Graal3D====
Again, since we don’t want to upload useless PrimitiveType prefabs to the server, we use this approach:
Again, since we don’t want to upload useless PrimitiveType prefabs to the server, we use this approach: ('''''Weapon:''''' ''3D/Samples/Examples/CircleFormation'')
{| class="wikitable"
findplayer("GraalID").addweapon(this.name);
|findplayer("GraalID").addweapon(this.name);
function onCreated() {
function onCreated() {
  temp.nbofobjects = 20;
 
  temp.radius = 5f;
  temp.nbofobjects = 20;
  for (temp.i = 0; temp.i < temp.nbofobjects; ++temp.i) {
 
    temp.angle = temp.i * Mathf::PI * 2 / temp.nbofobjects;
  temp.radius = 5f;
    temp.x1 = cos(temp.angle) * temp.radius;
 
    temp.y1 = sin(temp.angle) * temp.radius;
  for (temp.i = 0; temp.i < temp.nbofobjects; ++temp.i) {
    temp.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
 
    temp.cube.transform.position = v3(player.x + temp.x1, player.z, player.y + temp.y1);
    temp.angle = temp.i * Mathf::PI * 2 / temp.nbofobjects;
    temp.angleDegrees = -temp.angle * Mathf::Rad2Deg;
 
    temp.cube.transform.rotation = Quaternion::euler(0, temp.angleDegrees, 0);
    temp.x1 = cos(temp.angle) * temp.radius;
  }
 
}
    temp.y1 = sin(temp.angle) * temp.radius;
[[File:Circle formation graal3d.png|frameless|639x639px]]
 
    temp.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
 
    temp.cube.transform.position = Vector3::create(player.x + temp.x1, player.z, player.y + temp.y1);
 
    temp.angleDegrees = -temp.angle * Mathf::Rad2Deg;
 
    temp.cube.transform.rotation = Quaternion::euler(0, temp.angleDegrees, 0);
 
  }
 
}
|}[[File:Circle formation graal3d.png|frameless|639x639px]]


''Circle Formation - Graal Script''
''Circle Formation - Graal Script''
===Moving Cube Example - Using the Update function===
===Moving Cube Example - Using the Update function===
====Using Unity====
====Using Unity====
{| class="wikitable"
using System.Collections;
|using System.Collections;
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
 
public class MovingCube: MonoBehaviour {
using UnityEngine;
  GameObject cube;
 
  public int height = 10;
public class MovingCube: MonoBehaviour
  public float yCenter = 0f;
 
  void Start() {
{
    cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
 
    cube.transform.position = new Vector3(0, 0f, 0);
    GameObject cube;
  }
 
  void Update() {
    public int height = 10;
    cube.transform.position = new Vector3(cube.transform.position.x, yCenter + Mathf.PingPong(Time.time * 2, height) - height / 2f,       cube.transform.position.z);
 
  }
    public float yCenter = 0f;
}
 
''Moving Cube - C# Script''
    void Start()
 
    {
 
        cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
 
        cube.transform.position = new Vector3(0, 0f, 0);
 
    }
 
    void Update()
 
    {
 
        cube.transform.position = new Vector3(cube.transform.position.x, yCenter + Mathf.PingPong(Time.time * 2, height) - height / 2f, cube.transform.position.z);
 
    }
 
}
|}''C# Script''


Here we use the Update function. As its name suggests, it will serve to update gameplay and move the cube up and down depending on the time.
Here we use the Update function. As its name suggests, it will serve to update gameplay and move the cube up and down depending on the time.
====Using Graal3D====
====Using Graal3D====
{| class="wikitable"
('''''Weapon:''''' ''3D/Samples/Examples/MovingCube'')
|findplayer("GraalID").addweapon(this.name);
findplayer("GraalID").addweapon(this.name);
//#CLIENTSIDE
//#CLIENTSIDE
 
function onCreated(){
function onCreated(){
  this.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
 
  this.cube.transform.position = v3(player.x,player.z,player.y);
this.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
  this.height = 10;//max height of Box's movement
 
  this.yCenter = 0.0;
this.cube.transform.position = Vector3::create(player.x,player.z,player.y);
  SetTimer(0.001);
 
}
this.height = 10;//max height of Box's movement
 
function onTimeout() {
this.yCenter = 0.0;
  this.cube.transform.position = v3(this.cube.transform.position.x,this.yCenter + Mathf::PingPong(Time::time *2,   this.height)  - height / 2.0,this.cube.transform.position.z);
 
  SetTimer(0.001);
SetTimer(0.001);
}
 
Moving Cube - GraalScript
}
 
function onTimeout() {
 
this.cube.transform.position = Vector3::create(this.cube.transform.position.x,this.yCenter + Mathf::PingPong(Time::time *2, this.height)  - height / 2.0,this.cube.transform.position.z);
 
SetTimer(0.001);
 
}
|}GraalScript


Here the SetTimer() and onTimeout() functions replace the Update() function in Unity.
Here the '''''SetTimer()''''' and '''''onTimeout()''''' functions replace the '''''Update()''''' function in Unity.
===Cube with Physics - Using Physics and Collision===
===Cube with Physics - Using Physics and Collision===
In this example we will add physics to our Gameobject, it will be subject to gravity, forces and collisions with other Gameobjects. We will also see how to detect and handle these collisions.
In this example we will add physics to our Gameobject, it will be subject to gravity, forces and collisions with other Gameobjects. We will also see how to detect and handle these collisions.
{| class="wikitable"
|findplayer("GraalID").addweapon(this.name);
//#CLIENTSIDE


function onCreated() {
('''''Weapon:''''' ''3D/Samples/Examples/SimplePhysicObject'')
findplayer("GraalID").addweapon(this.name);
//#CLIENTSIDE
function onCreated() {
  SetTimer(9999);
  this.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
  this.cube.transform.position = v3(player.x + 5, player.z, player.y);
  this.cube.AddComponent(Type::RigidBody);
  Quattro::EventManager::AddOnCollisionHandlerTo(this.cube, this.cube.layer);
  this.catcheventobject(this.cube, "onCollisionEnter", "onCubeCollisionEnter");
}
public function onCubeCollisionEnter(gameobject, collision) {
  player.chat = "Collision!";
}
''Cube with Physics - Graal Script''


  SetTimer(9999);
We create and place a Cube just like the examples before.


  this.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
To add physics to the GameObject, we add the '''RigidBody Component''';
 
{| class="wikitable"
  this.cube.transform.position = Vector3::create(player.x + 5, player.z, player.y);
!this.cube.AddComponent(Type::RigidBody);
 
|}
  this.cube.AddComponent(Type::RigidBody);
Now to add a Collision Handler;
 
{| class="wikitable"
 
!''Quattro::EventManager::AddOnCollisionHandlerTo()''
  Quattro::EventManager::AddOnCollisionHandlerTo(this.cube, this.cube.layer);
|}
 
And
  this.catcheventobject(this.cube, "onCollisionEnter", "onCubeCollisionEnter");
{| class="wikitable"
 
!''this.catcheventobject(GameObject, “onCollisionEnter”, “onFunctionName”)''
}
|}
 
Which will catch collision and call the function '''''onFunctionName()''''' that you have to implement;
public function onCubeCollisionEnter(gameobject, collision) {
public function onCubeCollisionEnter(gameobject, collision) {
 
  player.chat = "Collision!";
  player.chat = "Collision!";
}
 
The two parameters:
}
|}''Cube with Physics - Graal Script''
 
We create and place a Cube just like the examples before. To add physics to the gameobject, we add the '''RigidBody Component'''.
 
The Quattro::EventManager::AddOnCollisionHandlerTo() function will a collision handler.


And this.catcheventobject(GameObject, “onCollisionEnter”, “nameOf”)
'''gameobject:''' it is the Gameobject that was just used to detect collision (''the cube in our example'')


The onCubeCollisionEnter(gameobject, collision) will trigger functionalities upon collision.
'''collision:''' describes the collider we hit, you can retrieve the GameObject collided with by using: '''''collision.GameObject'''.''


Note: Whenever we use collisions, the SetTimer(9999) is essential, it will keep the script alive and always checking for events.
'''Note:''' Whenever we use collisions, the '''''SetTimer(9999)''''' is essential; it will keep the script alive and always checking for events. the Unity function OnUpdate() will be triggered for every frame.

Latest revision as of 06:13, 12 October 2021

Here are a few examples for beginners wanting to get into Graal3D. You will need to have both the Worlds Client and RC downloaded. You will also need an authorized account to be able to login to the server.

  1. Download the build compressed file, uncompress it and run the Build application.
  2. Login with your GraalID and password, a window will open containing Worlds and Account info.
  3. Login to the erareloaded server by typing “erareloaded” in the bottom left server field and press Enter.


Once logged in, you're required to know how to use the tools that allow you to warp to different levels, debug your code... Unity tools are also available as well.

An explanation of all the tools is available here: Tools

Building a Wall Example - Creating prefabs and instantiating them

This example is found in the Unity Manual; We will build a wall using primitive type Cubes as Gameobjects. It will be demonstrated using Unity C# and on Graal3D using Graalscript.

Using Unity

Open the Unity editor with a new project.

Step1: Creating an empty Gameobject to hold our Script

To your scene add an empty Gameobject. To do that, right click in the Hierarchy Section (on the left) and click on Create Empty, place the created Gameobject in the scene in front of the camera.

This Gameobject will hold our script to build a wall.

1.png

Step2: Creating a Prefab

In the same way add a Cube Gameobject to the Hierarchy (right click in Hierarchy -> 3D Object -> Cube).

Now drag the Cube from the Hierarchy to the Assets Section to create a prefab (it will serve as a template to instantiate cubes). Rename the Cube to block (right click on the prefab -> rename).

2.png

Step3: Running the script

Now to the empty Gameobject we’ll need to add the script that builds a wall.

Press on the Gameobject in the Hierarchy, all its details will pop up in the Inspector Section (on the right). Press on Add Component and search for “script” to add a new script.

3.png

To modify the script, open it in your IDE and copy the C# script below.

Note: Make sure you name the public class the same name as your script file.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class wall: MonoBehaviour {
  public GameObject block;
  public int width = 10;
  public int height = 4;
  void Start(){
    for (int y = 0; y < height; ++y) {
      for (int x = 0; x < width; ++x) {
        Instantiate(block, new Vector3(x, y, 0), Quaternion.identity);
      }
    }
  }
}

Building a Wall - C# Script

Finally, you’ll need to add the block prefab that we’ve created earlier to script component (to replace the public Gameobject variable “block” in the script).

To do that, drag it from the assets folder to the script component.

Prefab.png


After having completed all the steps above, you should be able to start your scene, it will run all the scripts of the Gameobjects... et Voilà! A Wall!WallOnUnity.png

Wall with 10 Columns and 4 Rows                                           

Explanation:

A script needs to implement a class that extends the built-in class MonoBehavior.

public class wall: MonoBehaviour { }

The Start function is where you instantiate your Gameobjects.

The Update function is where the gameplay updates happen (Gameobject movement, triggering actions, taking user input...). It is similar to the onTimeOut / onMouseDown / onKeyPressed... functions in Graalscript.

Important Note:

Coordinates.png


Everything related to movement, direction, rotation, speed… in Unity is done using Vectors: new Vector3(x, y, z)

In unity the y axis represents the vertical axis (usually referred to as z)

Instantiate Function in Unity:

Instantiate(block, new Vector3(x, y, 0), Quaternion.identity);

Instantiate Function in Unity:

public static Object Instantiate(Object original, Vector3 position, Quaternion rotation);

In the example, the Object is the block and the rotation is

Quaternion.identity

to indicate 0 rotation.

Quaternions:

Quaternions are used to represent rotations. The most used Quaternion functions: Quaternion.LookRotation, Quaternion.Angle, Quaternion.Euler, Quaternion.Slerp, Quaternion.FromToRotation, and Quaternion.identity.

Another Way:

For primitive types there’s no need to actually create a prefab since they are recognized by Unity. We could have skipped step 2 where we create the prefab and modified our code to this:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class wall: MonoBehaviour {
  public int width = 10;
  public int height = 4;
  void Start() {
    for (int y = 0; y < height; ++y) {
      for (int x = 0; x < width; ++x) {
        GameObject.CreatePrimitive(PrimitiveType.Cube).transform.position = new Vector3(x, y, 0);
      }
    }
  }
}

Building a Wall - C# Script

Using Graal3D

We are going to mimic the second C# script since it would be useless to upload a Cube prefab to the server, when we can simply instantiate them using PrimitiveType.

The same script above will look like this in GraalScript: (Weapon: 3D/Samples/Examples/BuildingWall)

findplayer("GraalID").addweapon(this.name);
//#CLIENTSIDE
function onCreated() {
  this.width = 10;
  this.height = 4;
  for (temp.y = 0; temp.y < this.height; ++temp.y) {
    for (temp.x = 0; temp.x < this.width; ++temp.x) {
      GameObject::CreatePrimitive(PrimitiveType::Cube).transform.position = v3(player.x - 5 + temp.x, temp.y, player.y + 1);
    }
  }
}

Building a Wall - Graal Script

The two codes are almost the same except for:

  • The onCreated() function replaces the start() function
  • The “ . ” for methods is replaced by “:: ”

Function format: Unity C#: Type.method => Graal Script: Type::Method

  • v3(x,y,z) replaces new Vector3(x,y,z)
  • The Gameobject is instantiated close to the player using (player.x and player.y)

Wall.png

Wall with 10 Columns and 4 Rows

Circle Formation Example - Using Rotation and Mathf functions

This example is similar to the one above, we’ll instantiate the Cubes in a circular shape with rotation so that they all point towards the player.

Using Unity

Just like in the previous example; create a new script file named “CircleFormation”, open it in you editor and copy paste this code:

using UnityEngine;
public class CircleFormation: MonoBehaviour {
  public GameObject prefab;
  public int numberOfObjects = 20;
  public float radius = 5f;
  void Start() {
    for (int i = 0; i < numberOfObjects; i++) {
      float angle = i * Mathf.PI * 2 / numberOfObjects;
      float x = Mathf.Cos(angle) * radius;
      float z = Mathf.Sin(angle) * radius;
      Vector3 pos = transform.position + new Vector3(x, 0, z);
      float angleDegrees = -angle*Mathf.Rad2Deg;
      Quaternion rot = Quaternion.Euler(0, angleDegrees, 0);
      Instantiate(prefab, pos, rot);
    }
  }
}

Circle Formation - C# Script

Create an empty Gameobject in the Hierarchy, add the script to it (as a component).

Add a Cube Gameobject to the Hierarchy (right click -> 3D Object -> Cube).

Now drag the Cube from the Hierarchy to the Assets Section to create a prefab, rename it to “prefab” to be referenced by the script. Finally add it to the script on the Empty Gameobject and hit run.

Circle formation unity.png

Explanation:

In this example we use the Mathf collection, a struct containing all the static math methods.

https://docs.unity3d.com/ScriptReference/Mathf.html for all the methods.

We also use the Quaternion.Euler to rotate the cubes. You can rotate around whatever axis you want, in our example Quaternion.Euler(0, angleDegress, 0) rotates the cubes around the y axis.

Another Way:

Just like before we could’ve just used GameObject.CreatePrimitive(PrimitiveType.Cube) to create the cubes and then change the transform.position and the transform.rotation.

Using Graal3D

Again, since we don’t want to upload useless PrimitiveType prefabs to the server, we use this approach: (Weapon: 3D/Samples/Examples/CircleFormation)

findplayer("GraalID").addweapon(this.name);
function onCreated() {
  temp.nbofobjects = 20;
  temp.radius = 5f;
  for (temp.i = 0; temp.i < temp.nbofobjects; ++temp.i) {
    temp.angle = temp.i * Mathf::PI * 2 / temp.nbofobjects;
    temp.x1 = cos(temp.angle) * temp.radius;
    temp.y1 = sin(temp.angle) * temp.radius;
    temp.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
    temp.cube.transform.position = v3(player.x + temp.x1, player.z, player.y + temp.y1);
    temp.angleDegrees = -temp.angle * Mathf::Rad2Deg;
    temp.cube.transform.rotation = Quaternion::euler(0, temp.angleDegrees, 0);
  }
}

Circle formation graal3d.png

Circle Formation - Graal Script

Moving Cube Example - Using the Update function

Using Unity

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingCube: MonoBehaviour {
  GameObject cube;
  public int height = 10;
  public float yCenter = 0f;
  void Start() {
    cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
    cube.transform.position = new Vector3(0, 0f, 0);
  }
  void Update() {
    cube.transform.position = new Vector3(cube.transform.position.x, yCenter + Mathf.PingPong(Time.time * 2, height) - height / 2f,       cube.transform.position.z);
  }
}

Moving Cube - C# Script

Here we use the Update function. As its name suggests, it will serve to update gameplay and move the cube up and down depending on the time.

Using Graal3D

(Weapon: 3D/Samples/Examples/MovingCube)

findplayer("GraalID").addweapon(this.name);
//#CLIENTSIDE
function onCreated(){
  this.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
  this.cube.transform.position = v3(player.x,player.z,player.y);
  this.height = 10;//max height of Box's movement
  this.yCenter = 0.0;
  SetTimer(0.001);
}

function onTimeout() {
  this.cube.transform.position = v3(this.cube.transform.position.x,this.yCenter + Mathf::PingPong(Time::time *2,    this.height)  - height / 2.0,this.cube.transform.position.z);
  SetTimer(0.001);
}

Moving Cube - GraalScript

Here the SetTimer() and onTimeout() functions replace the Update() function in Unity.

Cube with Physics - Using Physics and Collision

In this example we will add physics to our Gameobject, it will be subject to gravity, forces and collisions with other Gameobjects. We will also see how to detect and handle these collisions.

(Weapon: 3D/Samples/Examples/SimplePhysicObject)

findplayer("GraalID").addweapon(this.name);
//#CLIENTSIDE
function onCreated() {
  SetTimer(9999);
  this.cube = GameObject::CreatePrimitive(PrimitiveType::Cube);
  this.cube.transform.position = v3(player.x + 5, player.z, player.y);
  this.cube.AddComponent(Type::RigidBody);
  Quattro::EventManager::AddOnCollisionHandlerTo(this.cube, this.cube.layer);
  this.catcheventobject(this.cube, "onCollisionEnter", "onCubeCollisionEnter");
}

public function onCubeCollisionEnter(gameobject, collision) {
  player.chat = "Collision!";
}

Cube with Physics - Graal Script

We create and place a Cube just like the examples before.

To add physics to the GameObject, we add the RigidBody Component;

this.cube.AddComponent(Type::RigidBody);

Now to add a Collision Handler;

Quattro::EventManager::AddOnCollisionHandlerTo()

And

this.catcheventobject(GameObject, “onCollisionEnter”, “onFunctionName”)

Which will catch collision and call the function onFunctionName() that you have to implement;

public function onCubeCollisionEnter(gameobject, collision) {
  player.chat = "Collision!";
}

The two parameters:

gameobject: it is the Gameobject that was just used to detect collision (the cube in our example)

collision: describes the collider we hit, you can retrieve the GameObject collided with by using: collision.GameObject.

Note: Whenever we use collisions, the SetTimer(9999) is essential; it will keep the script alive and always checking for events. the Unity function OnUpdate() will be triggered for every frame.