Week 1.5: Implementing Knife Throwing in VR

This week, I focused on adding a knife throwing mechanic to my Unity VR project. The goal was to let the player grab knives from their belt, throw them using VR controls, and have them stick to walls. Here’s how I approached the task and what I learned along the way.

Designing the Knife Throwing System

I broke the system into several key components:

  • KnifeDetection: Handles player input for grabbing a knife, supporting both keyboard (for testing) and VR controller actions.
  • ThrowableKnife: Manages the number of knives available, spawns new knives in the player’s hand, and updates the belt knife display.
  • KnifeWallStick: Makes thrown knives stick to walls by changing their physics properties on collision.
  • AmmoManager: Keeps track of all spawned knives and controls the maximum number of knives in the scene.

KnifeDetection

This script checks if the player presses the X key or the VR grab action. When triggered, it calls the method to grab and spawn a knife. This allows for easy testing on both PC and VR hardware.

public class KnifeDetection : MonoBehaviour
{
public ThrowableKnife knife;
public InputActionProperty grabAction;

private void Update()
{
if (Input.GetKeyDown(KeyCode.X) || grabAction.action.WasPressedThisFrame())
{
knife.GrabKnife();
}
}
}

ThrowableKnife

This class keeps track of how many knives the player has left. When the player grabs a knife, it instantiates a throwable knife prefab at the hand’s position and reduces the count. The belt knife model is shown or hidden based on remaining knives.

public class ThrowableKnife : MonoBehaviour
{
public GameObject beltKnife, throwableKnifePrefab;
public Transform handTransform;
public int maxKnives = 6;
private int knivesRemaining;

private void Start()
{
knivesRemaining = maxKnives;
UpdateKnifeBelt();
}

public void GrabKnife()
{
if (knivesRemaining > 0)
{
Instantiate(throwableKnifePrefab, handTransform.position, handTransform.rotation);
knivesRemaining--;
UpdateKnifeBelt();
}
}
void UpdateKnifeBelt()
{
beltKnife.SetActive(knivesRemaining > 0);
}
}

KnifeWallStick

When a thrown knife collides with an object tagged “Wall,” it becomes kinematic, making it stick in place. This gives a satisfying effect of knives embedding into surfaces.

public class KnifeWallStick : MonoBehaviour
{
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Wall"))
{
GetComponent<Rigidbody>().isKinematic = true;
}
}
}

AmmoManager

This script manages the total number of knives in the scene. It spawns new knives if under the max limit and removes them when needed.

public class AmmoManager : MonoBehaviour
{
public GameObject daggerPrefab;
public int maxKnifeAmmo = 6;
private List<GameObject> knifeAmmoList = new List<GameObject>();

public void SpawnAmmo(Vector3 position)
{
if (knifeAmmoList.Count < maxKnifeAmmo)
{
GameObject ammo = Instantiate(daggerPrefab, position, Quaternion.identity);
knifeAmmoList.Add(ammo);
}
else
{
Debug.Log("No ammo");
}
}
public void RemoveAmmo(GameObject ammo)
{
knifeAmmoList.Remove(ammo);
Destroy(ammo);
}
}

What Went Well

  • Modular Design: Splitting the logic into separate scripts made it easier to debug and expand.
  • VR and Keyboard Support: Testing was smooth thanks to supporting both input types.
  • Visual Feedback: The belt knife model updates as knives are used, giving clear feedback to the player.

Challenges & Next Steps

  • Knife Alignment: Getting the knife to align perfectly in the hand took some trial and error with transforms.
  • Wall Detection: Ensuring only walls (and not other objects) trigger the stick effect required careful use of tags.
  • Future Improvements: I plan to add sound effects and maybe particle effects when knives stick to walls, and to improve the throwing physics for more realism.

This week’s work laid the foundation for interactive weapon mechanics in my VR project. Next, I’ll refine the throwing experience and add more feedback to make it even more immersive.

Leave a comment

Design a site like this with WordPress.com
Get started