patterncsharpMinor
Roll-a-ball controller
Viewed 0 times
rollballcontroller
Problem
I've been toying around with Unity 5 lately, and in an effort to start making an actual game, I've built a ball controller similar to the one found in the Unity tutorial Roll-a-ball.
In essence, the player controls a small ball that rolls around a "level". The ball can accelerate at a rate in the range \$1\rightarrow10\$ depending on what I (the designer) choose. The controller also manually calculates drag to create a "low-gravity" feel, but still have a sense of speed. Drag is calculated using the following formula:
$$\text{drag}=\frac{\text{acceleration vector magnitude}}{\text{some dividend}}$$
I'm wondering about the following things:
BallController.cs
```
using UnityEngine;
using System.Collections.Generic;
///
/// This class contains various methods and attributes
/// used to control the "vehicle".
///
[System.Serializable]
[RequireComponent(typeof(Rigidbody))]
public class MoveVehicle : MonoBehaviour
{
///
/// The force of an acceleration. This will be applied
/// to the ball when it's accelerating.
///
[Range(1, 10)]
public float accelerationForce;
///
/// This determines the drag being exerted on the ball
/// as it moves. Drag is determined through the formula
/// drag = accelerationForce / dragDividend
///
[Range(0, 1000)]
public float dragDividend;
private Rigidbody rigidBody;
private Dictionary keyMappings = new Dictionary() {
{KeyCode.Space, new Vector3(0, 5.5f, 0)},
{KeyCode.W, new Vector3(0, 0, 1)},
{KeyCode.A, new Vector3(-1, 0, 0)},
{KeyCode.S, new
In essence, the player controls a small ball that rolls around a "level". The ball can accelerate at a rate in the range \$1\rightarrow10\$ depending on what I (the designer) choose. The controller also manually calculates drag to create a "low-gravity" feel, but still have a sense of speed. Drag is calculated using the following formula:
$$\text{drag}=\frac{\text{acceleration vector magnitude}}{\text{some dividend}}$$
I'm wondering about the following things:
- Is it appropriate for the controller to do things such as drag calculation, or should this be separated into a separate area?
- I'm currently using a dictionary, looping through it, checking for keypresses, and then applying force if a key is pressed. Is this a good way to handle it? Will this ever slow anything down?
- Are there any performance improvements that can be made?
- Anything else?
BallController.cs
```
using UnityEngine;
using System.Collections.Generic;
///
/// This class contains various methods and attributes
/// used to control the "vehicle".
///
[System.Serializable]
[RequireComponent(typeof(Rigidbody))]
public class MoveVehicle : MonoBehaviour
{
///
/// The force of an acceleration. This will be applied
/// to the ball when it's accelerating.
///
[Range(1, 10)]
public float accelerationForce;
///
/// This determines the drag being exerted on the ball
/// as it moves. Drag is determined through the formula
/// drag = accelerationForce / dragDividend
///
[Range(0, 1000)]
public float dragDividend;
private Rigidbody rigidBody;
private Dictionary keyMappings = new Dictionary() {
{KeyCode.Space, new Vector3(0, 5.5f, 0)},
{KeyCode.W, new Vector3(0, 0, 1)},
{KeyCode.A, new Vector3(-1, 0, 0)},
{KeyCode.S, new
Solution
First let us nitpick a little bit.
The method in question
here I would suggest to use
Otherwise your code looks nice and tidy. Good job.
I don't know
If it is likely that the
MoveVehicle would be a nice name for a method but for a class it isn't choosen well. A class name should be made out of a noun or a noun phrase. So for instance VehicleMover or VehicleController would be a much better name for this class. The method in question
public void FixedUpdate()
{
foreach(KeyValuePair keyMapping in this.keyMappings)
{
if(Input.GetKey(keyMapping.Key) && this.IsGrounded())
{
Vector3 objectForce = keyMapping.Value * this.accelerationForce;
this.rigidBody.drag = objectForce.sqrMagnitude / this.dragDividend;
this.rigidBody.AddForce(objectForce);
}
}
}here I would suggest to use
var rather than KeyValuePair which would make your code a little bit cleaner and its obvious that it will be a KeyValuePair<TKey,TValue. Otherwise your code looks nice and tidy. Good job.
I don't know
Unity3D at all, so I don't know if it is possible to switch the public float accelerationForce; to a public property. If this is possible, I would suggest inside the setter to change all the values of the Dictionary so they represent the objectforce. This would involve a second kind of collection or some constants to hold the currently predifined values of the current Dictionary. If it is likely that the
accelerationForce is called less often than the FixedUpdate() method this will speed the whole thing up.Code Snippets
public void FixedUpdate()
{
foreach(KeyValuePair<KeyCode, Vector3> keyMapping in this.keyMappings)
{
if(Input.GetKey(keyMapping.Key) && this.IsGrounded())
{
Vector3 objectForce = keyMapping.Value * this.accelerationForce;
this.rigidBody.drag = objectForce.sqrMagnitude / this.dragDividend;
this.rigidBody.AddForce(objectForce);
}
}
}Context
StackExchange Code Review Q#107086, answer score: 5
Revisions (0)
No revisions yet.