コード例 #1
0
        private ThryBP_Glass GetClosestGlassToPredictedTableCollision(Vector3 prediction)
        {
            //Get Cup closest to that point
            ThryBP_Glass aimedCup        = null;
            float        closestDistance = float.MaxValue;

            for (int p = 0; p < _mainScript.playerCountSlider.local_float; p++)
            {
                float d = 0;
                foreach (ThryBP_Glass cup in _mainScript.players[p].cups.activeGlassesGameObjects)
                {
                    if (cup == null)
                    {
                        continue;
                    }
                    if (cup.player.playerIndex == currentPlayer)
                    {
                        continue;
                    }
                    d = Vector3.Distance(cup.transform.position, prediction);
                    if (d < closestDistance)
                    {
                        closestDistance = d;
                        aimedCup        = cup;
                    }
                }
            }
            return(aimedCup);
        }
コード例 #2
0
        void DoRimming()
        {
            if (rimming < RIMMING_TOTAL_AGULAR_ROTATION)
            {
                ThryBP_Glass cup = _mainScript.GetCup(state[1], state[2], state[3]);
                if (Utilities.IsValid(cup))
                {
                    rimming += RIMMING_SPEED * Time.deltaTime;

                    float inside    = 0.9f - rimming / RIMMING_TOTAL_AGULAR_ROTATION * 0.15f;
                    float downwards = 1 - rimming / RIMMING_TOTAL_AGULAR_ROTATION * 0.3f;
                    float angle     = (rimming - Mathf.Pow(rimming * 0.009f, 2)) / cup.circumfrence * 0.4f;
                    transform.position = cup.transform.position + Vector3.up * (cup.GetBounds().size.y *downwards)
                                         + Quaternion.Euler(0, angle, 0) * Vector3.forward * (cup.radius * cup.transform.lossyScale.x * inside - _radius);
                }
            }
            else
            {
                ThryBP_Glass cup = _mainScript.GetCup(state[1], state[2], state[3]);
                if (Utilities.IsValid(cup))
                {
                    cup.colliderInside.SetActive(true);
                    cup.colliderForThrow.enabled = false;
                    _rigidbody.velocity          = Quaternion.Euler(0, 90 + rimming, 0) * Vector3.forward * 0.3f;  //in circle
                    _rigidbody.velocity         += Quaternion.Euler(0, rimming + 180, 0) * Vector3.forward * 0.1f; //inwards
                    _rigidbody.velocity         += Vector3.down * 0.1f;                                            //downwards
                    SetDynamic();
                    localState     = STATE_IN_CUP;
                    stateStartTime = Time.time;
                    _TriggerSplash();
                    _pickup.pickupable = !autoRespawnBallAfterCupHit;
                }
            }
        }
コード例 #3
0
        private Vector3 DoAIVectoring(Vector3 velocity, Vector3 position, float skill)
        {
            if (skill == 0)
            {
                return(velocity);
            }
            //Get Point where ball will hit table
            Vector3      predictionTableHit = PredictTableHit(velocity, position, tableHeight);
            ThryBP_Glass cup = GetClosestGlassToPredictedTableCollision(predictionTableHit);

            if (cup == null)
            {
                return(velocity);
            }
            Vector3 cupOpening    = cup.transform.position + Vector3.up * cup.GetBounds().size.y;
            Vector3 optimalVector = OptimalVectorChangeStrength(velocity, position, cup);

            float lerping = Random.Range(0f, 1f);

            if (lerping < skill)
            {
                lerping = 1;
            }
            velocity = Vector3.Lerp(velocity, optimalVector, lerping);

            return(velocity);
        }
コード例 #4
0
        //Instanciating

        public void InstanciateGlass(int row, int collum, int index)
        {
            float   relativeX = (float)collum - MAX_ROWS;
            Vector3 position  = new Vector3(relativeX * glass.radius * scale, 0, row * glass.diameter * scale);

            GameObject instance = VRCInstantiate(glass.gameObject);

            instance.transform.SetParent(anchors[anchor_id]);
            instance.transform.localPosition = position + position_offset;
            instance.transform.localRotation = Quaternion.identity;
            instance.transform.localScale    = Vector3.one * scale;
            instance.SetActive(true);

            ThryBP_Glass thryglass = instance.GetComponent <ThryBP_Glass>();

            thryglass.row             = row;
            thryglass.collum          = collum;
            thryglass.player          = _player;
            thryglass.anchor_id       = anchor_id;
            thryglass.position_offset = position_offset;
            thryglass.radius          = glass.radius;
            thryglass.diameter        = glass.diameter;
            thryglass.circumfrence    = glass.circumfrence;

            activeGlassesGameObjects[index] = thryglass;

            SetColor(thryglass, index);
        }
コード例 #5
0
        //=========Collision Code======

        private void ResetLastCupsColliders()
        {
            ThryBP_Glass cup = _mainScript.GetCup(state[1], state[2], state[3]);

            if (Utilities.IsValid(cup))
            {
                cup.colliderForThrow.enabled = true;
                cup.colliderInside.SetActive(false);
            }
        }
コード例 #6
0
        private void BallGlassCollision(Collision collision, ThryBP_Glass hitGlass)
        {
            Bounds b = hitGlass.GetBounds();
            bool   isCollisionOnTop = (b.max.y < transform.position.y);

            SetDynamic();

            if (isCollisionOnTop)
            {
                Vector3 p1 = transform.position;
                p1.y = 0;
                Vector3 p2 = hitGlass.transform.position;
                p2.y = 0;
                float distanceFromCenter = Vector3.Distance(p1, p2) / ((b.extents.x + b.extents.z) / 2);

                if (distanceFromCenter < COLLISION_MAXIMUM_DISTANCE_FROM_CENTER)
                {
                    float angle = Vector3.Angle(_lastvelocies[_lastvelociesHead], Vector3.down);
                    //bool tripOnEdge = distanceFromCenter > Random.Range(0, 0.85f);
                    bool tripOnEdge = distanceFromCenter > Random.Range(0.4f, 0.7f) && angle > Random.Range(45, 80); //if it lands really flat chances are higher for it to ride edge

                    if (tripOnEdge)
                    {
                        SetState(STATE_RIMING);
                        state[1] = (byte)hitGlass.player.playerIndex;
                        state[2] = (byte)hitGlass.row;
                        state[3] = (byte)hitGlass.collum;
                        rimming  = Vector3.Angle(hitGlass.transform.rotation * Vector3.forward, p2 - p1);
                        if ((p2 - p1).x > 0)
                        {
                            rimming = 360 - rimming;
                        }
                        rimming  = rimming % 360;
                        state[4] = (byte)(rimming / 2);
                        state[5] = (byte)(distanceFromCenter * 100);
                    }
                    else
                    {
                        hitGlass.colliderForThrow.enabled = false;
                        hitGlass.colliderInside.SetActive(true);
                        _pickup.pickupable = !autoRespawnBallAfterCupHit;
                        SetState(STATE_IN_CUP);
                        state[1] = (byte)hitGlass.player.playerIndex;
                        state[2] = (byte)hitGlass.row;
                        state[3] = (byte)hitGlass.collum;

                        _TriggerSplash();
                        _rigidbody.velocity = Vector3.down * startVelocityLocal.magnitude;
                    }
                    RequestSerialization();
                }
            }
        }
コード例 #7
0
        //=======Array syncing========

        public void SetColor(ThryBP_Glass g, int index)
        {
            if (_player.randomColor)
            {
                UnityEngine.Random.InitState(index);
                g.SetColor(new Color(UnityEngine.Random.value, UnityEngine.Random.value, UnityEngine.Random.value));
            }
            else
            {
                g.SetColor(_player.playerColor);
            }
        }
コード例 #8
0
        void DoInCup()
        {
            ThryBP_Glass cup = _mainScript.GetCup(state[1], state[2], state[3]);

            if (Utilities.IsValid(cup))
            {
                //if ball is not in cup teleport ball in cup
                Collider c = cup.colliderForThrow;
                c.enabled = true;
                Vector3 cPoint = c.ClosestPoint(transform.position);
                c.enabled = false;
                Bounds b = cup.GetBounds();
                b.size = b.size += Vector3.up;
                if (Vector3.Distance(cPoint, transform.position) > 0.01f && ((_rigidbody.velocity.sqrMagnitude == 0) || (b.Contains(transform.position) == false)))
                {
                    //Debug.Log($"cPoint: {cPoint.ToString("F3")} point: {transform.position.ToString("F3")}");
                    //Debug.Log($"[ThryBP] Teleported ball into cup ({state[1]},{state[2]},{state[3]})");
                    transform.position = cup.GetBounds().center;
                }
                else if (Networking.IsOwner(gameObject))
                {
                    if (_mainScript.gamemode == 0)
                    {
                        if (Time.time - stateStartTime > (autoRespawnBallAfterCupHit ? 2 : 20))
                        {
                            _mainScript.CountCupHit(state[1], state[2], state[3], currentPlayer, state[0] == STATE_RIMING ? 1 : 0);
                            _mainScript.RemoveCup(state[1], state[2], state[3], currentPlayer);
                            Respawn();
                        }
                    }
                    else if (_mainScript.gamemode == 1)
                    {
                        if (Time.time - stateStartTime > 1)
                        {
                            _mainScript.CountCupHit(state[1], state[2], state[3], currentPlayer, state[0] == STATE_RIMING ? 1 : 0);
                            _mainScript.RemoveCup(state[1], state[2], state[3], currentPlayer);
                            Respawn();
                        }
                    }
                    else if (_mainScript.gamemode == 2)
                    {
                        if (Time.time - stateStartTime > 3)
                        {
                            _mainScript.CountCupHit(state[1], state[2], state[3], currentPlayer, state[0] == STATE_RIMING ? 1 : 0);
                            Respawn();
                        }
                    }
                }
            }
        }
コード例 #9
0
        private void OnCollisionEnter(Collision collision)
        {
            if (collision.collider == null || collision.collider.gameObject == null)
            {
                return;
            }

            bool hasHitGlass = collision.collider.gameObject.GetComponent <ThryBP_Glass>() != null;

            if (hasHitGlass)
            {
                PlayAudio(audio_collision_glass, startVelocityLocal.sqrMagnitude / 10);
            }
            else
            {
                PlayAudio(audio_collision_table, startVelocityLocal.sqrMagnitude / 10);
            }

            startPositionLocal         = transform.position;
            startVelocityLocal         = Vector3.Reflect(VelocityAtTime(startVelocityLocal, Time.time - physicsSimulationStartTime), Vector3.up) * BOUND_DRAG;
            physicsSimulationStartTime = Time.time;

            if (Networking.IsOwner(gameObject))
            {
                if (state[0] == STATE_FYING)
                {
                    if (hasHitGlass)
                    {
                        ThryBP_Glass hitGlass = collision.collider.gameObject.GetComponent <ThryBP_Glass>();
                        //check if collision with own glass and if friendly fire is turned on
                        if (_mainScript.AllowCollision(currentPlayer, hitGlass.player))
                        {
                            BallGlassCollision(collision, hitGlass);
                        }
                    }
                    //none beer pong object => miss
                    else if (collision.collider.gameObject.name.StartsWith("[ThryBP]") == false)
                    {
                        Debug.Log("[ThryBP] Ball hit non game object. Respawning for other team.");
                        NextTeam();
                        Respawn();
                    }
                }
            }
        }
コード例 #10
0
        private Vector3 DoAimbotVectoring(Vector3 velocity, Vector3 position, float strength)
        {
            if (strength == 0)
            {
                return(velocity);
            }
            //Get Point where ball will hit table
            Vector3      predictionTableHit = PredictTableHit(velocity, position, tableHeight);
            ThryBP_Glass cup = GetClosestGlassToPredictedTableCollision(predictionTableHit);

            if (cup == null)
            {
                return(velocity);
            }
            Vector3 cupOpening    = cup.transform.position + Vector3.up * cup.GetBounds().size.y;
            Vector3 hitOnCupPlane = PredictTableHit(velocity, position, cupOpening.y);

            if (Vector3.Distance(cupOpening, hitOnCupPlane) > strength)
            {
                return(velocity);
            }
            return(OptimalVectorChangeStrength(velocity, position, cup));
        }
コード例 #11
0
        private Vector3 OptimalVectorChangeAngle(Vector3 velocity, Vector3 position, float tableHeight, ThryBP_Glass aimedCup)
        {
            //Calculate trajectory to that cup
            Vector3 horizonzalDistance = aimedCup.transform.position - position;

            horizonzalDistance.y = 0;
            //https://www.youtube.com/watch?v=bqYtNrhdDAY&ab_channel=MichelvanBiezen
            //https://www.youtube.com/watch?v=pQ23Eb-bXvQ&ab_channel=MichelvanBiezen
            float g     = -Physics.gravity.y;
            float v2    = velocity.sqrMagnitude;
            float x     = horizonzalDistance.magnitude;
            float h     = position.y - (tableHeight + aimedCup.GetBounds().size.y);
            float phi   = Mathf.Atan(x / h);
            float theta = (Mathf.Acos(((g * x * x / v2) - h) / Mathf.Sqrt(h * h + x * x)) + phi) / 2;

            Vector3 newVel = (horizonzalDistance.normalized * Mathf.Cos(theta) + Vector3.up * Mathf.Sin(theta)) * velocity.magnitude;

            if (float.IsNaN(theta))
            {
                //cant reacht cup with current velocity
                //just aim in it's direction instead
                Vector3 horizontalVel = velocity;
                horizontalVel.y = 0;
                newVel          = horizonzalDistance.normalized * horizontalVel.magnitude;
                newVel.y        = velocity.y;
            }
            return(newVel);
        }
コード例 #12
0
        private Vector3 OptimalVectorChangeStrength(Vector3 velocity, Vector3 position, ThryBP_Glass cup)
        {
            Vector3 cupOpening       = cup.transform.position + Vector3.up * cup.GetBounds().size.y;
            Vector3 horizonzalVector = cupOpening - position;

            horizonzalVector.y = 0;
            Vector3 horizonzalVelocity = velocity;

            horizonzalVelocity.y = 0;
            //https://www.youtube.com/watch?v=mOYJKv22qeQ&list=PLX2gX-ftPVXUUlf-9Eo_6ut4kP6wKaSWh&index=7&ab_channel=MichelvanBiezen
            // d = v0 * cos(w) * t
            // => t = d / (v0 * cos(w))
            // y = y0 + v0 * sin(w) * t - 0.5 * g * t2
            // y = y0 + v0 * sin(w) * ( d / (v0 * cos(w)) ) - 0.5 * g * ( d / (v0 * cos(w)) )2
            // y = y0 + tan(w) * d - 0.5 * g * ( d / (v0 * cos(w)) )2
            // y0 - y + tan(w) * d = 0.5 * g * ( d / (v0 * cos(w)) )2
            // 2(y0 - y + tan(w) * d) / g = ( d / (v0 * cos(w)) )2
            // sqrt( 2(y0 - y + tan(w) * d) / g) = d / (v0 * cos(w))
            // v0 * cos(w) = d / sqrt( 2(y0 - y + tan(w) * d) / g)
            // v0 = d / sqrt( 2(y0 - y + tan(w) * d) / g) / cos(w)
            float d  = horizonzalVector.magnitude;
            float y0 = position.y;
            float y  = cupOpening.y;
            float w  = Mathf.Deg2Rad * Vector3.Angle(horizonzalVelocity, velocity);
            float g  = -Physics.gravity.y;

            float v0 = d / Mathf.Sqrt(2 * (y0 - y + Mathf.Tan(w) * d) / g) / Mathf.Cos(w);

            Vector3 newDirection = horizonzalVector.normalized * horizonzalVelocity.magnitude;

            newDirection.y = velocity.y;

            return(newDirection.normalized * v0);
        }
コード例 #13
0
        public override void OnDeserialization()
        {
            _pickup.pickupable = state[0] == STATE_IDLE || (state[0] == STATE_IN_CUP && !autoRespawnBallAfterCupHit);
            SetColor();

            if (state[0] == STATE_IDLE)
            {
                SetStatic();
                transform.position = start_position;
                transform.rotation = start_rotation;
                startVelocityLocal = Vector3.zero;
            }
            else if (state[0] == STATE_IN_HAND)
            {
                SetStatic();
                throwIndicator.gameObject.SetActive(false);
            }
            else if (state[0] == STATE_LOCKED)
            {
                transform.position = start_position;
                transform.rotation = start_rotation;
                throwIndicator.SetPositionAndRotation(transform.position, transform.rotation);
                throwIndicator.gameObject.SetActive(true);
            }
            else if (state[0] == STATE_FYING)
            {
                transform.position         = start_position;
                transform.rotation         = start_rotation;
                startPositionLocal         = start_position;
                startVelocityLocal         = start_velocity;
                physicsSimulationStartTime = Time.time;
                SetStaticCollisions();
                throwIndicator.gameObject.SetActive(false);
            }
            else if (state[0] == STATE_RIMING)
            {
                rimming = state[4] * 2;
            }
            else if (state[0] == STATE_IN_CUP)
            {
                ThryBP_Glass cup = _mainScript.GetCup(state[1], state[2], state[3]);
                if (Utilities.IsValid(cup))
                {
                    cup.colliderForThrow.enabled = false;
                    cup.colliderInside.SetActive(true);
                }
            }

            if (state[0] != localState)
            {
                localState     = state[0];
                stateStartTime = Time.time;

                if (localState == STATE_IDLE || localState == STATE_FYING)
                {
                    ResetLastCupsColliders();
                }
                if (localState == STATE_IN_CUP)
                {
                    _TriggerSplash();
                }
            }
        }