Example #1
0
    // Use this for initialization
    public void Start()
    {
        bc = GetComponent <BaseController> ();
        if (bc == null)
        {
            Debug.LogError("Base Controller is null");
        }

        ps = GameObject.FindObjectOfType <PlayerSpawner> ();
        if (ps == null)
        {
            Debug.LogError("Player Spawner is null");
        }

        tm = GameObject.FindObjectOfType <TextManager> ();
        if (tm == null)
        {
            Debug.LogError("Text Manager is null");
        }

        hitPoints     = bc.GetHealth();
        currentPoints = hitPoints;

        // @DEBUG(sdsmith): Add entry to debug overlay
        DebugOverlay.AddAttr("Max health", hitPoints.ToString());
        DebugOverlay.AddAttr("Current health", currentPoints.ToString());
    }
    /**
     * Return true if the character is on the ground, false otherwise.
     */
    private bool IsGrounded()
    {
        /*
         * @NOTE(sdsmith): There was issues with steep slopes when one ray was
         * shot downward from the center. The fix is shooting one ray every 90
         * degrees of the circumference of the collider.
         *                                                         - 2017-02-13
         *
         * @PERFORMANCE(sdsmith): Do we want to unroll this, short circuit it,
         * keep it the same? I perfer consistent timing for an operation this
         * common rather than fluctuating performance. However, it could be
         * argued that the general case is being on mostly level ground, which
         * would short ciruit it on the first of second ray. The downside is
         * you get a potential 4x slowdown on steep slopes.
         *                                                         - 2017-02-13
         */
        const float errorMargin    = 0.5F;
        float       colliderRadius = collider.radius;

        bool hit = false;

        for (float deltaX = -colliderRadius; deltaX <= colliderRadius; deltaX += 2 * colliderRadius)
        {
            for (float deltaZ = -colliderRadius; deltaZ <= colliderRadius; deltaZ += 2 * colliderRadius)
            {
                Vector3 delta = new Vector3(deltaX, 0, deltaZ);
                hit = hit || Physics.Raycast(transform.position + delta, -Vector3.up, errorMargin);
                //Debug.DrawRay(transform.position + delta, -Vector3.up * errorMargin, Color.yellow, 5);
            }
        }

        DebugOverlay.AddAttr("isGrounded", hit.ToString());

        return(hit);
    }
    protected void Start()
    {
        // Component references
        rigidbody   = GetComponent <Rigidbody>();
        collider    = GetComponent <CapsuleCollider>();
        audioSource = GetComponent <AudioSource>();

        jumpSpeed = 5f;
        isJumping = IsGrounded();
        isAirborn = isJumping;

        oldMoveInput = Vector3.zero;

        // @DEBUG(Llewellin): Add entry to debug overlay
        DebugOverlay.AddAttr("speed", GetSpeed().ToString());
        DebugOverlay.AddAttr("damage", GetDamage().ToString());
    }
Example #4
0
    [PunRPC]     // can be called indirectly
    // all players recieve notification of something taking damage
    public virtual void TakeDamage(float amt, int attackerViewID)
    {
        currentPoints -= amt;

        // Play player damage notification
        if (gameObject.tag == "Player")
        {
            PlayerController pc = gameObject.GetComponent <PlayerController>();
            Debug.Assert(pc != null, "Object tagged as 'Player' does not have a 'PlayerController'");
            pc.PlayTakenDamageNotification();
        }

        // @DEBUG(sdsmith): Update debug stats
        // @TODO(sdsmith): @PERFORMANCE(sdsmith): Should have these calls
        // wrapped under a debug flag to reduce performance impact of the
        // calls when the overlay is not enabled.
        //if (this.gameObject.GetComponent<PhotonView>().isMine) {
        DebugOverlay.AddAttr("Current health", currentPoints.ToString());
        //}

        if (currentPoints <= 0)
        {
            Die();
            SetStats(attackerViewID);
            SendKillMessage(attackerViewID);

            // Play kill sound for attacker
            PhotonView pv = PhotonView.Find(attackerViewID);
            if (pv)
            {
                // Player that hit this target is still alive, play the notification
                // @NOTE(sdsmith): If this is placed before 'Die()', players do not
                // die. Who knows.
                pv.gameObject.GetComponent <PlayerController>().PlayKillNotification();
            }

            // Play death sound for killed player
            AudioClip clip = AudioClips.GetRand(AudioClips.playerDeath);
            AudioSource.PlayClipAtPoint(clip, this.gameObject.transform.position, 1.5f);
        }
    }
Example #5
0
    void Fire()
    {
        if (coolDown > 0)
        {
            return;
        }

        //changed
        if (gameObject.GetComponent <GrabAndDrop> ().GetGrabbedObject() != null)
        {
            return;
        }

        // Play fire/throw sound
        AudioClip clip = AudioClips.GetRand(AudioClips.playerThrow);

        audioSource.PlayOneShot(clip);

        // Fire the snowball
        if (fxManager != null)
        {
            // @DEBUG(sdsmith): Update debug stats
            DebugOverlay.AddAttr("snowballs fired count", (++firedSnowballsCount).ToString());

            /*
             * @TODO(Llewellin): change the startPos to be where the snowball launches.
             * @NOTE(Llewellin): startPos is set forward slightly so the snowball doesn't come from the camera.
             * The camera is inside the player, which causes the snowball to hit us and causes complications in
             * SnowballController:onCollisionEnter().
             * i.e. we collide with ourselves and take damage, then die
             */

            // @TODO(sdsmith): Set offset of the snowball spawn location to be relative to the size of the player's
            // collider plus the width of the snowball collider and some error margin to make it change proof.
            Vector3 startPos     = Camera.main.transform.position + (Camera.main.transform.forward * 1.1f);
            int     playerViewID = this.gameObject.GetComponent <PhotonView>().viewID;
            fxManager.GetComponent <PhotonView>().RPC("SnowballFX", PhotonTargets.All, startPos, Camera.main.transform.rotation, snowballDamage, playerViewID);
        }

        coolDown = fireRate;
    }
    void OnCollisionEnter(Collision collision)
    {
        // Play snowball impact sound
        //
        // @NOTE(sdsmith): Must use AudioSource.PlayClipAtpoint so the clip
        // persists after the destruction of the object. If we ere using an
        // AudioSource component, the clip would stop playing once that
        // component was destroyed.
        AudioClip impactClip = AudioClips.GetRand(AudioClips.snowballImpacts);

        AudioSource.PlayClipAtPoint(impactClip, transform.position);


        if (collision.gameObject.name == "Mountain")
        {
            // @NOTE(sdsmith): @PERFORMANCE(sdsmith): Note that 'Destroy'
            // delayed at least until the end of the frame update cycle. If we
            // hit the terrain, we know we don't need to do any additional
            // collision calculations.
            //
            // @TODO(sdsmith): This breaks Network manager when we take the advice
            // of the above comment and end the function here. Who knows.
            //                                                        - 2017-02-27
            Destroy(this.gameObject);
        }

        // @DEBUG(sdsmith): Update debug overlay
        DebugOverlay.AddAttr("snowball collision count", (++nonTerrainCollisionCount).ToString());

        Transform hitTransform = collision.transform;

        // If we hit something, lets resolve the hit
        if (hitTransform != null)
        {
            // Debug.Log ("HIT: " + collision.gameObject.name);
            Health h = hitTransform.GetComponent <Health>();

            // check if the things parent has a Health object
            while (h == null && hitTransform.parent)
            {
                hitTransform = hitTransform.parent;
                h            = hitTransform.GetComponent <Health>();
            }

            // The thing we hit has a health component
            // Tell the thing we hit to take damage
            if (h != null)
            {
                PhotonView pv = h.GetComponent <PhotonView>();
                if (pv == null)
                {
                    Debug.Log("PlayerShooting: PhotonView is null");
                }
                else
                {
                    //get the thing that was hit
                    PhotonPlayer target = pv.owner;

                    // Get teams
                    PunTeams.Team ourTeam   = PhotonNetwork.player.GetTeam();
                    PunTeams.Team theirTeam = PunTeams.Team.none; // default objects to no team

                    // Check if the target object has an owner
                    // @NOTE(sdsmith): PhotonView.owner is null for scene objects
                    // https://doc-api.photonengine.com/en/pun/current/class_photon_view.html#ad696cb93fb9835d633b9def970650edc
                    if (target != null)
                    {
                        // Target has an owner (not a scene object), set its team
                        theirTeam = target.GetTeam();
                    }

                    if (ourTeam != theirTeam)
                    {
                        // Not targeting same team
                        pv.RPC("TakeDamage", PhotonTargets.AllBuffered, damage, throwerViewID);

                        // Play hit sound if our local client threw the snowball
                        PhotonView throwerPV = PhotonView.Find(throwerViewID);
                        if (throwerPV && Util.localPlayer == throwerPV.gameObject)
                        {
                            throwerPV.gameObject.GetComponent <PlayerController>().PlayHitNotification();
                        }
                    }
                    else
                    {
                        // Targeting same team
                    }
                }
            }
            Destroy(this.gameObject);
        }
    }