---
# System prepended metadata

title: Assignment 4 - More objects to your world (graded)

---

# Assignment 4 - More objects to your world (graded)

**Date**: 27/02/2022

**Group members participating**: Jakob Overgaard (201706812), Oilver Rask Schmahl (201805260), Tobias Fabrin Gade (201809466)

**Activity duration**: 8-10 hours on average per person.

## Goal
Our goal for this week was to finilize our concept and to start getting our hands on proper 3D assets to be used in our "Urban Planning" AR application. 

## Plan
1. Solve Exercise.
2. Concretize the concept idea.
3. Brainstorm object interaction (rotate, scale, etc...).

## Results
**Exercise 1.1**
For creating a UI catalogue where users can select different objects to spawn, we create an addition menu button which opens an object selection UI overlay over the users screen - the button simply calls ToggleObjectSelectionUI function when it is clicked. The function for opening and closing the UI can be seen below: 
(Note: We use an external library called LeanTween, to make the UI animate, by just shifting it's position - this is much more efficient than Unity's animation library, because animations would result in the UI updating every frame, even when it is not animated)

```C#
public void ToggleObjectSelectionUI()
{
    RectTransform rectTransform = objectSelectionUI.GetComponent<RectTransform>();;
    if (_objectSelectionUIToggled == false)
    {
        LeanTween.moveY(rectTransform, -rectTransform.rect.height, 0.2f);
        _objectSelectionUIToggled = true;
        return;
    }
    LeanTween.moveY(rectTransform, 0, 0.2f);
    _objectSelectionUIToggled = false;
}
```

When the objectAdderScript is initialized we create buttons for all prefabs stored in the "spawnable objects" resource folder and add them to the object selection UI menu. Additionally this code is also responsible for adding event listeners for when these buttons are clicked and changing the objectToSpawn variable to the newly selected object. The code for this can be seen below:

```C#
private void Start()
{
    // Get all game objects in the resource folder "spawnable objects".
    Object[] spawnableObjects = Resources.LoadAll("Spawnable Objects", typeof(GameObject));
            
    // For each of these spawnable objects create a button inside the object selection UI to select it.
    foreach (var spawnableObject in spawnableObjects)
    {
        // We get the name of the spawnable object (so the prefabs name in the resource folder).
        String objectName = spawnableObject.name;
        // We get the empty game object/UI element which all buttons should be a child of.
        Transform buttonHolder = objectSelectionUI.transform.GetChild(1);
        // We take out button template and instantiate.
        Button newButton = Instantiate(objectButtonTemplate, buttonHolder);
                
        // We set the button name to the same as the prefab name
        newButton.name = objectName;
                
        // We get the first child of the button, which is a text element, and change the text to the prefab name
        var buttonText = newButton.transform.GetChild(0);
        buttonText.GetComponent<TextMeshProUGUI>().text = objectName;
                
        // We add an event listener to when the button is clicked
        // - when this happens we call the select object function passing the prefab as a GameObject.
        newButton.onClick.AddListener(() => SelectObject(spawnableObject as GameObject));
    }
}

```

The function that is called to change the object to spawn is very simple, it simply assigns the selected prefab to the objectToSpawn variable. Code below:

```C#
private void SelectObject(GameObject spawnableObject)
{
    // Select object function just changes the object to spawn variable to the newly selected object prefab.
    objectToSpawn = spawnableObject;
    // And then removes the UI
    ToggleObjectSelectionUI();
}
```

At the moment things are functional, however we have some touble understanding how to layer things. The UI for the selection menu is for example correctly placed over the camera, but the spawned objects are rendered in front of the UI - we are a bit unsure how to best solve this. This would be nice to get some hints towards.

The object selection in app can be seen in the gif below:

**!!!!! Insert gif!!!!!**

**Exercise 2.1**
For adding animations to the objects, we added a new button under the object manipulation UI that is shown when the object is selected. When this button is clicked a new RotationAnimation script is added onto the selected object, this script is fairly simple and is intended to just be a display animation that lets the user needly see the object rotating. If the script already exist on the object is it removed instead.

The code for this can be seen below:

The Animation Script:
```C#
void Update()
{
    transform.Rotate(0, 50*Time.deltaTime, 0);
}
```

Code for adding or removing the objects animation:
```C#
public void ToggleObjectAnimation()
{
    if (_selectedGameObject.GetComponent<RotateAnimation>() == null)
    {
        _selectedGameObject.gameObject.AddComponent<RotateAnimation>();
        return;
    }
    Destroy(_selectedGameObject.GetComponent<RotateAnimation>());
}
```

Below is a gif of how it functions in the app:
**!!!!! Insert gif!!!!!**


**Exercise 2.2**
So for the exercise concerning customization of the objects, we have some touble with our concept. Our concept features placing 3D models of architecture for users to walk around and study in smaller scale. Since these models are very large and comprised of many different elements and textures we find it way to cumbersome to add customization to them - what we have chosen to do instead, is to add a cube prefab, that can also be placed next to the achitecture, that will show our solution on the customization exercise and how to change objects materials.

Code for changing the material of our object:
```C#
public void MaterialToBody()
{
    var objectRenderer = _selectedGameObject.GetComponent<Renderer>();
    objectRenderer.GetComponent<MeshRenderer>().material = body;
}
```

Below is a gif of how it functions in the app:
**!!!!! Insert gif!!!!!**