[Mounts] Help!

I have a horse model with animations. I want to be able to mount that horse by clicking on it being able to run around as the horse with the character attached. Can someone help? Thank you

Bump need this ASAP

I haven’t done this before but I can give some suggestions.

One, you could make a copy of the horse and its animations that have the character attached to it. Once you’ve got that you’d just use script to remove the character and normal horse and replace them with the mounted horse and to switch from controlling the character to controlling the mounted horse. (I think World of Warcraft does it this way.)

Two, you could have an animation for the character that’s in a riding position (and also one for mounting / dismounting) and use script to make it stay relative to where the horse is as it moves, again using script to switch from controlling the character to controlling the horse (I think Red Dead Redemption does it this way.)

Either way you’ll need to make new animations. Software such as Motionbuilder is good for doing this, but there are alternatives such as Blender that aren’t quite as easy to animate in.

I do not care for the animations at this point. The character for all I could care if walk up to my horse model (Which already has animations) and the character to be in a standing position for now. It doesn’t bother me I will get to the PROPER anims asap. If you could tell me how to do so? It would be excellent. I am sure there is a way for you to walk up to it press E for example and Jump on the horse disabling the Characters functions and enabling the horse to act as the character?

try having a look for “scripts to enter a vehicle”…
for example:

the majority talk about GTA clones, but the concept of transferring control from the player character model to another model (car, horse, boat, whatever) is the same. In the horse case you’ll need to put the player character model (just the mesh i would think) on the saddle.

I’m so dense I think I might need a step by step tutorial :frowning: FFS -.-

I’ve made a script that should work and be a basis. It may need some adjustments and can be improved alot, it’s written in ~ 10-15 mins though and should rather represent the basic idea that i would use when i need such a script:

This is the full class, rename the script you put it into like the class or name the class like your scriptname.

In order to test this, you’ll need at least the following in your scene:

  1. player onject , mount object

  2. player object only needs to have the script attached to it and, for easy testing, a rigidbody ( not using gravity and set to isKinematic) in order to make the triggering work (you can replace it by a CharacterController too and ajust the movement code)

  3. your mount object needs a childObject, which i called ‘mountTrigger’ … i used a simple cube and rescaled it so that it covers the area around the mount, disable the renderer and set the collider component to ‘isTrigger’

  4. add the tag ‘mount’ to this childObject

  5. if i haven’t forgot to mention anything, this should be working and give you a basic idea

using UnityEngine;
using System.Collections;

public class playerMountControl : MonoBehaviour {

    private bool useMount; // are we in range of the mount?
    //private bool mounted; // this was actually implemented for further control when mounted, not needed at this current state

    public Transform mountObject; // the reference for the mount object that we will sit on
    public Transform objControl;     // reference to the transform that our movement input will affect

    public Vector3 mountedPos;    // the position the player will be moved to when we use the mount
    public float moveSpeed = 2f;    // player's walking speed
    public float mountSpeed = 3f;   // additional speed through the mount

    void Start () 
    {
        useMount = false;               // to be sure it's false in the beginning, let's explicitly tell unity to do so
        //mounted = false;
        objControl = transform;        // in the beginning we want to move our player, thus we put the object's transform this script is attached to
    }
	
	
	void Update () 
    {
        if (useMount  Input.GetKeyDown(KeyCode.E))  // if we entered the mountTrigger and press E
        { 
            mountObject.FindChild("mountTrigger").gameObject.SetActive(false); // just to prevent some bugs, disable the trigger temporarily
            useMount = false; // we don't want the GUI to show the message anymore and do not want this code to be able to be executed again while we sit on the mount
            //mounted = true;

            transform.parent = mountObject.transform; // parent the player to the mount so that he moves with its transform
            objControl = mountObject; // now we want to control the mountObject, not the player itself anymore
            mountedPos = mountObject.position + Vector3.up; // you can also use a gameObject for the position offset 
           //so that you can adjust it in runtime/inspector by moving it instead of editing the script or a public vector variable
            moveSpeed += mountSpeed; // let's add the speed for the movement, don't forget to remove it when unmounting

            transform.position = mountedPos; // let's finally put the player object onto the mount
        }

        if(Input.GetKey(KeyCode.W))
        {
            objControl.Translate(Vector3.forward*moveSpeed*Time.deltaTime); // just move forward
        }
        if(Input.GetKey(KeyCode.S))
        {
            objControl.Translate(Vector3.back *moveSpeed* Time.deltaTime); // backwards
        }
        
        // more input
        // plus it's better to make a movement vector and first add all the input, 
        // transform the direction to worldspace and normalize the vector before moving 
	}

    void OnGUI()
    {
        if (useMount) // when this is set to true, we want the text to be shown
        {
            GUI.Label(new Rect(Screen.width/2-50, Screen.height/2-10, 100,20), "Press 'E' to use the mount!");
        }
    }

    void OnTriggerEnter(Collider trigger)
    {
        // enable the Label showing further instructions and 'enable' the key input for mounting
        // but only do so if the trigger we entered is the trigger of a mount
        if (trigger.tag == "mount")
        {
            useMount = true; // now we enable the piece of code in update, so that only the key needs to be pressed
            mountObject = trigger.transform.parent; // let's already get the mount in our range, which is the parent object of our trigger
        }
    }

    void OnTriggerExit(Collider trigger)
    {
        // disable the piece of code for mounting when we exit that trigger
        if (trigger.tag == "mount")
        {
            useMount = false; // disable the code so that we can press E as often as we want when we do not enter a mountTrigger
            mountObject = null; // i don't know why, this may cause some exceptions later
            // but also prevents bugs like attaching us to the wrong object whatever... needs to be checked whether it's null or not whenever you try to do something with the object this is
            // you can remove it if you want to
        }
    }
}

Dont suppose you could PM me about this to talk further about that matter?

Did it work as you expected or is there something that didn’t work/ you wanted to have different.
You can PM me whenever you want to, but i’m not a professional developer.

However, if you want to ask first and come to forums whenever i cannot help you, you can do this too.

  • void Update ()
  • {
  • if (useMount & Input.GetKeyDown(KeyCode.E)) // if we entered the mountTrigger and press E
  • {

Put “&” between useMount and Input, fixes the errors from what may have been a typo.

Haha yes, that was typed in the browser… I hate to look at code that I wrote 5 years ago. Wouldn’t recommend to use the code “as is”. It’s not that good.

Should be “&&”, not “&”.

Single works for me.

When press “E”, my character does not appear on top of my mount while the mount is moving? Only the mount will move around.

The above script parents the mount to the player, so the player should move when the mount transform moves. Maybe you have a weird setup where you constantly overwrite your player position in worldspace, or you made a mistake. As this is a 10 year old thread in which not even the OP bothered to reply anymore, i would suggest just making a new thread.