Posted on

Ball Roll Mechanic with Add Force in Unity

In this video, We talk more about our marble game group Unity project. I explain that I will be updating this Unity project on a weekly basis. I hope that you will join this group project and help us create levels in Unity for this game.

Project Page: https://www.infogamerhub.com/collaborative-unity-project-1/

We will also show you how to create a ball roll mechanic in Unity. We are using a ball roll mechanic for this group Unity project. Ball rolling is a very popular game mechanic found in many video games. If you haven’t learned how to make a ball roll in Unity then this is the video for you as I show you how to create a basic but effective ball prefab that you can use in any of your unity projects.

Unlock Code and Member Content

BasicForceMovement.cs

using UnityEngine;
using UnityEngine.InputSystem;

namespace InfoGamer
{
    public class BasicForceMovement : MonoBehaviour
    {
        Rigidbody myRB;

        [SerializeField] InputAction WASDInput;
        Vector2 movementInput;
        [SerializeField] float force;

        [SerializeField] float topXZSpeed;
        [SerializeField] float topYSpeed;


        private void OnEnable()
        {
            WASDInput.Enable();
        }

        private void OnDisable()
        {
            WASDInput.Disable();
        }

        // Start is called before the first frame update
        void Start()
        {
            if(topYSpeed > 0)
            {
                topYSpeed *= -1;
            }
            myRB = GetComponent<Rigidbody>();
        }

        private void Update()
        {
            movementInput = WASDInput.ReadValue<Vector2>();
        }

        
        void FixedUpdate()
        {

            myRB.AddForce(new Vector3(movementInput.x, 0, movementInput.y) * force);

            if (myRB.velocity.y < topYSpeed)
            {
                myRB.velocity = new Vector3(myRB.velocity.x, topYSpeed, myRB.velocity.z);
            }
            Vector2 tempXZ = new Vector2(myRB.velocity.x, myRB.velocity.z);
            if (tempXZ.magnitude > topXZSpeed)
            {
                tempXZ = tempXZ.normalized * topXZSpeed;
                myRB.velocity = new Vector3(tempXZ.x, myRB.velocity.y, tempXZ.y);
            }


            Debug.Log(myRB.velocity);
        }
    }
}

BasicForceJump.cs

using UnityEngine;
using UnityEngine.InputSystem;

namespace InfoGamer
{
    public class BasicForceJump : MonoBehaviour
    {
        Rigidbody myRB;

        [SerializeField] InputAction JumpInput;

        [SerializeField] float jumpForce;

        private void OnEnable()
        {
            JumpInput.performed += Jump;
            JumpInput.Enable();
        }

        private void OnDisable()
        {
            JumpInput.performed -= Jump;
            JumpInput.Disable();
        }

        private void Start()
        {
            myRB = GetComponent<Rigidbody>();
        }

        private void Jump(InputAction.CallbackContext obj)
        {
            //Debug.Log("Jump");
            bool isGrounded = false;
            if (Physics.Raycast(transform.position, Vector3.down, transform.localScale.y/2 + .1f))
            {
                isGrounded = true;
            }
            if (!isGrounded)
                return;

            if (obj.ReadValue<float>() > 0)
            {
                myRB.AddForce(0, jumpForce, 0);
            }
        }
    }
}
using Photon.Chat;
using Photon.Pun;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class PhotonChatManager : MonoBehaviour, IChatClientListener
{
    #region Setup

    [SerializeField] GameObject joinChatButton;
    ChatClient chatClient;
    bool isConnected;
    [SerializeField] string username;

    public void UsernameOnValueChange(string valueIn)
    {
        username = valueIn;
    }

    public void ChatConnectOnClick()
    {
        isConnected = true;
        chatClient = new ChatClient(this);
        //chatClient.ChatRegion = "US";
        chatClient.Connect(PhotonNetwork.PhotonServerSettings.AppSettings.AppIdChat, PhotonNetwork.AppVersion, new AuthenticationValues(username));
        Debug.Log("Connenting");
    }

    #endregion Setup

    #region General

    [SerializeField] GameObject chatPanel;
    string privateReceiver = "";
    string currentChat;
    [SerializeField] InputField chatField;
    [SerializeField] Text chatDisplay;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (isConnected)
        {
            chatClient.Service();
        }

        if (chatField.text != "" &amp;&amp; Input.GetKey(KeyCode.Return))
        {
            SubmitPublicChatOnClick();
            SubmitPrivateChatOnClick();
        }
    }

    #endregion General

    #region PublicChat

    public void SubmitPublicChatOnClick()
    {
        if (privateReceiver == "")
        {
            chatClient.PublishMessage("RegionChannel", currentChat);
            chatField.text = "";
            currentChat = "";
        }
    }

    public void TypeChatOnValueChange(string valueIn)
    {
        currentChat = valueIn;
    }

    #endregion PublicChat

    #region PrivateChat

    public void ReceiverOnValueChange(string valueIn)
    {
        privateReceiver = valueIn;
    }

    public void SubmitPrivateChatOnClick()
    {
        if (privateReceiver != "")
        {
            chatClient.SendPrivateMessage(privateReceiver, currentChat);
            chatField.text = "";
            currentChat = "";
        }
    }

    #endregion PrivateChat

    #region Callbacks

    public void DebugReturn(DebugLevel level, string message)
    {
        //throw new System.NotImplementedException();
    }

    public void OnChatStateChange(ChatState state)
    {
        if(state == ChatState.Uninitialized)
        {
            isConnected = false;
            joinChatButton.SetActive(true);
            chatPanel.SetActive(false);
        }
    }

    public void OnConnected()
    {
        Debug.Log("Connected");
        joinChatButton.SetActive(false);
        chatClient.Subscribe(new string[] { "RegionChannel" });
    }

    public void OnDisconnected()
    {
        isConnected = false;
        joinChatButton.SetActive(true);
        chatPanel.SetActive(false);
    }

    public void OnGetMessages(string channelName, string[] senders, object[] messages)
    {
        string msgs = "";
        for (int i = 0; i &lt; senders.Length; i++)
        {
            msgs = string.Format("{0}: {1}", senders[i], messages[i]);

            chatDisplay.text += "\n" + msgs;

            Debug.Log(msgs);
        }

    }

    public void OnPrivateMessage(string sender, object message, string channelName)
    {
        string msgs = "";

        msgs = string.Format("(Private) {0}: {1}", sender, message);

        chatDisplay.text += "\n " + msgs;

        Debug.Log(msgs);
        
    }

    public void OnStatusUpdate(string user, int status, bool gotMessage, object message)
    {
        throw new System.NotImplementedException();
    }

    public void OnSubscribed(string[] channels, bool[] results)
    {
        chatPanel.SetActive(true);
    }

    public void OnUnsubscribed(string[] channels)
    {
        throw new System.NotImplementedException();
    }

    public void OnUserSubscribed(string channel, string user)
    {
        throw new System.NotImplementedException();
    }

    public void OnUserUnsubscribed(string channel, string user)
    {
        throw new System.NotImplementedException();
    }

    #endregion Callbacks
}