Various questions

ncho

New member
I bought Third Person Controller and creating a character through the usual setup, then shooting at it leads to bullet decals showing up on the capsule collider bounds but not on the actual mesh. How do I fix this?

In addition I'm trying to create a surface effect in which objects get parented immediately to the character hit after spawning. So I would guess that I would have to do something like this in SurfaceEffect.cs but I'm not sure how to get the right object for the character to parent to here?

Code:
   /// <summary>
        /// Instantiates the Spawned Objects.
        /// </summary>
        /// <param name="hit">The RaycastHit which caused the collision.</param>
        /// <param name="gravityDirection">The normalized direction of the character's gravity.</param>
        private void SpawnObjects(RaycastHit hit, Vector3 gravityDirection)
        {
            for (int i = 0; i < m_SpawnedObjects.Length; ++i) {
                if (m_SpawnedObjects[i] == null) {
                    continue;
                }

                m_SpawnedObjects[i].Instantiate(hit.point, hit.normal, gravityDirection);
                m_SpawnedObjects[i].Object.transform.SetParent() ///How to get the right character here?
            }
        }

Lastly, I'm trying to make it so that the rotation of objects spawned in a Surface Effect changes according to the angle of the bullet impact (and not totally random as with "Random Spin"). But not even sure where to start with that.

Thanks for the help.
 
Last edited:
I bought Third Person Controller and creating a character through the usual setup, then shooting at it leads to bullet decals showing up on the capsule collider bounds but not on the actual mesh. How do I fix this?
This isn't built in but I imagine that you could modify the decal manager to support this. There also may be an asset on the store which helps with this.

In addition I'm trying to create a surface effect in which objects get parented immediately to the character hit after spawning. So I would guess that I would have to do something like this in SurfaceEffect.cs but I'm not sure how to get the right object for the character to parent to here?
The hit parameter specifies the object that was hit so you could do some filtering based on that.

Lastly, I'm trying to make it so that the rotation of objects spawned in a Surface Effect changes according to the angle of the bullet impact (and not totally random as with "Random Spin"). But not even sure where to start with that.
You could modify the Surface Effect to indicate if a rotation should be applied based on the angle, and then when instantiating the object within the Surface Manager you would apply that rotation.
 
OK I see I guess, I don't understand why the controller uses the big inaccurate capsule collider for the receiving damage and decals to begin with when there are more precise colliders on the individual limbs and torso? I also don't understand what the Collider Positioner does exactly. Out of the box the hit detection and decals are just very inaccurate because of this. I kind of assumed this would be a perfectly solved problem in the TPCC just as in the other areas but am I right in assuming it's very barebones there or am I missing something?
How can I make the hit detection use the individual bone colliders?
 
Also - I'm trying to integrate this with a third party decal solution now and got this so far with the help of that asset's developer:

C#:
using UnityEngine;
using Opsive.UltimateCharacterController.Events;
using SkinnedDecals;

public class DamageDecalCreator : MonoBehaviour
{

    public SkinnedDecalSystem skinnedDecals;

    public SkinnedDecal damageDecal;
    public GameObject bloodEffect;
    public void Awake()
    {
        // Subscribe to OnHealthDamage-event
        EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, Collider>(gameObject, "OnHealthDamage", OnImpact);
    }

    private void OnImpact(float amount, Vector3 position, Vector3 force, GameObject attacker, Collider hitCollider)
    {
        // Where the bullet came
        Vector3 origin = attacker.transform.position;
        // Bullet travel direction
        Vector3 direction = (position - origin).normalized;
        // Create decal
        skinnedDecals.CreateDecal(damageDecal, origin, direction);

    }
}

But I need to change some things about this - first I want this to trigger not only on damage but also when the character is already dead ie at any time when a projectile impacts that character's collider. There is an event OnObjectImpact mentioned for hitscan weapons but I'm using a projectile and can't find what I should use then. Is it OnCollision? That doesn't seem to work though.

Also attacker.transform.position needs to be replaced by either the fire point of the firing weapon or the position of the projectile impact - I am not sure which one it should be? But I can't figure out how to get that either.

Sorry if these are really newbie questions I'm figuring this out as I go.
 
Last edited:
I don't understand why the controller uses the big inaccurate capsule collider for the receiving damage and decals to begin with when there are more precise colliders on the individual limbs and torso?
For most games using the main capsule collider is accurate enough. Both UFPS 1 and TPC 1 used this method so I brought it over to version 2. I can see in the future using the ragdoll colliders but right now there are higher priority items.

I also don't understand what the Collider Positioner does exactly.
It resizes the collider so it matches the character's height/rotation. This is especially useful when the character is crouching so it automatically readjusts.
How can I make the hit detection use the individual bone colliders?
I haven't done this before so I don't have a step by step solution, but one way may be to always keep the ragdoll colliders enabled and setup the layer masks so things like firing a bullet will hit those ragdoll colliders. You will probably also need to write some code which has certain colliders ignore other colliders because normally the ragdoll colliders aren't enabled at the same time as the main collider.

There is an event OnObjectImpact mentioned for hitscan weapons but I'm using a projectile and can't find what I should use then.
You can use OnObjectImpact as well for projectiles.
 
Hi Justin thanks for the answers. I ask because honestly I don't know how most games solve this, as mentioned I'm pretty new to this, but with the current capsule collider I can very easily aim at areas clearly outside the character mesh and it still gets registered as a hit. Or above the shoulders / besides the head. Is that how it's supposed to be out of the box? The collider is by design where the actual projectile impact is registered, no? So I thought that bone colliders would be the only way to get better results.

You can use OnObjectImpact as well for projectiles.

I ask because the documentation says: " This callback only occurs when firing with a hitscan. The projectile contains a similar callback that can be used" but maybe I misunderstood this.
 
Is that how it's supposed to be out of the box? The collider is by design where the actual projectile impact is registered, no?
That's correct.

I ask because the documentation says: " This callback only occurs when firing with a hitscan. The projectile contains a similar callback that can be used" but maybe I misunderstood this.
I can see how that can be confusing. I'll reword it and add the same callback info to the projectile page.
 
So then would this be supposed to work attached to my enemy because it doesn't and also no events get logged:

C#:
using UnityEngine;
using Opsive.UltimateCharacterController.Events;
using SkinnedDecals;

public class MyObject : MonoBehaviour
{
    public SkinnedDecalSystem skinnedDecals;

    public SkinnedDecal damageDecal;

    /// <summary>
    /// Initialize the default values.
    /// </summary>
    public void Awake()
    {
        EventHandler.RegisterEvent<float, Vector3, Vector3, GameObject, Collider>(gameObject, "OnObjectImpact", OnImpact);
    }

    /// <summary>
    /// The object has been impacted with another object.
    /// </summary>
    /// <param name="amount">The amount of damage taken.</param>
    /// <param name="position">The position of the damage.</param>
    /// <param name="forceDirection">The direction that the object took damage from.</param>
    /// <param name="attacker">The GameObject that did the damage.</param>
    /// <param name="hitCollider">The Collider that was hit.</param>
    private void OnImpact (float amount, Vector3 position, Vector3 forceDirection, GameObject attacker, Collider hitCollider)
    {
        Vector3 origin = attacker.transform.position;
        Vector3 direction = (position - origin).normalized;
        skinnedDecals.CreateDecal(damageDecal, origin, direction);
        Debug.Log(name + " impacted by " + attacker + " on collider " + hitCollider + ".");
    }

    /// <summary>
    /// The GameObject has been destroyed.
    /// </summary>
    public void OnDestroy()
    {
        EventHandler.UnregisterEvent<float, Vector3, Vector3, GameObject, Collider>(gameObject, "OnObjectImpact", OnImpact);
    }
}
 
As long as the enemy collider is the one that was hit then that looks like it should work. You can debug this by placing a breakpoint within Destructible.OnCollision and seeing what object the event was sent to.
 
Top