🏐 Ultimate Volleyball: A 3D Volleyball environment built using Unity ML-Agents
Tags: unity3d, machinelearning, ai, reinforcementlearning
Published: 2021-08-11 02:13:33

Inspired by [Slime Volleyball Gym](https://github.com/hardmaru/slimevolleygym), I built a 3D Volleyball environment using Unity's [ML-Agents toolkit](https://github.com/Unity-Technologies/ml-agents). The full project is open-source and available at: [🏐 Ultimate Volleyball](https://github.com/CoderOneHQ/ultimate-volleyball).

If you're interested in an overview of the implementation details, challenges and learnings — read on! For a background on ML-Agents, please check out my [Introduction to ML-Agents article](https://medium.com/nerd-for-tech/an-introduction-to-machine-learning-with-unity-ml-agents-af71938ca958).

>**Versions used:** Release 18 (June 9, 2021)
>**Python package:** 0.27.0
>**Unity package:** 2.1.0

## 🥅 Setting up the court

Here's what I used:

- Agent Cube prefabs from the ML-Agents sample projects
- Volleyball prefab & sand material from this [free Beach Essentials Asset Pack](https://assetstore.unity.com/packages/3d/props/free-beach-essentials-asset-pack-131149)
- Net, walls and floor made up of resized & rotated cube objects (net material from [Free Grids & Nets Materials Pack](https://assetstore.unity.com/packages/2d/textures-materials/yughues-free-grids-nets-materials-13004))
- Thin floor representing the blue and purple "goals"

![Volleyball](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/55z1pwu5h9tay9girrqs.PNG)

Some other implementation details: 

- The agent cubes have a **sphere** collider to help control the ball trajectory
- I used 2 layers for the ground: the thin 'goals' on top, and the walkable floor below it. Since the goal colliders are set as 'triggers' (to check when the ball hits the floor), they will no longer register collisions. Hence the walkable floor is used for collision physics instead.
- I also added an invisible boundary around the court. I found that during training, agents may shy away from learning to hit the ball at all if you penalize them for hitting the ball out of bounds.

## 📃 Scripts

4 scripts were used to define the environment:

- `VolleyballAgent.cs` ([Link](https://github.com/CoderOneHQ/ultimate-volleyball/blob/master/Assets/Scripts/VolleyballAgent.cs))
    - Defines observations
    - Controls agents' movement & jump actions
- `VolleyballController.cs` ([Link](https://github.com/CoderOneHQ/ultimate-volleyball/blob/master/Assets/Scripts/VolleyballController.cs))
    - Checks whether the ball has hit the floor, and triggers allocation of rewards in `VolleyballEnv.cs`
- `VolleyballEnv.cs` ([Link](https://github.com/CoderOneHQ/ultimate-volleyball/blob/master/Assets/Scripts/VolleyballEnvController.cs))
    - Randomises spawn positions
    - Controls starting/stopping of an episode
    - Allocates rewards to agents
- `VolleyballSettings.cs` ([Link](https://github.com/CoderOneHQ/ultimate-volleyball/blob/master/Assets/Scripts/VolleyballSettings.cs))
    - Contains basic settings e.g. agent's run speed and jump height

## 🤖 Agents

I planned to train the agents using PPO + Self-Play. To set this up:

- Set 'Team Id' under Behavior Parameters to identify opposing teams (0 = blue, 1 = purple)
- Ensure the environment is symmetric

### Observations:

Total observation space size: 11

- Rotation (Y-axis) - *1*
- 3D Vector from agent to the ball - *3*
- Distance to the ball - *1*
- Agent velocity (X, Y & Z-axis) - *3*
- Ball velocity (X, Y & Z-axis) - *3*

An alternative to vector observations is to use [Raycasts](https://learn.unity.com/tutorial/let-s-try-shooting-with-raycasts#5c7f8528edbc2a002053b468).

### Available actions

4 discrete branches:

- Move forward, backward, stay still (size: 3)
- Move left, right, stay still (size: 3)
- Rotate left, right, stay still (size: 3)
- Jump, no jump (size: 2)

## 🍭 Rewards

Self-play is finicky, and I had many unstable runs. From the [ML-Agents documentation of Self-Play](https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Training-Configuration-File.md#self-play), they suggest keeping the rewards simple (+1 for the winner, -1 for the loser) and allowing for more training iterations to compensate.

## 📚 Resources

For others looking to build their own environments, I found these resources helpful:

- [Hummingbirds Course](https://learn.unity.com/course/ml-agents-hummingbirds) by Unity (unfortunately outdated, but still useful).
- [ML-Agents Sample Environments](https://github.com/Unity-Technologies/ml-agents/blob/main/docs/Learning-Environment-Examples.md#:~:text=The%20Unity%20ML%2DAgents%20Toolkit,Agents%2FExamples%20and%20summarized%20below.) (particularly the Soccer & Wall Jump environments)

---

## 👟 Next steps

Thanks for reading!

Next, I'll share my learnings training an agent using PPO + self-play.

If you're interested in [trying out the environment yourself](https://github.com/CoderOneHQ/ultimate-volleyball), you can submit your model to play against others. [Sign up](https://bit.ly/ulti-volleyball) to get notified when submissions open.

Any feedback and suggestions are welcome.