MagicItem Improvements

devomage

Member
When trying to set MagicItem dynamically, all of the Actions do not work. Here is an example of adding CastActions where 'item' is the Fireball MagicItem on Nolan.

The screenshot shows the Inspector during the Cast. The array is a bit wonky looking...

C#:
#region CastActions

var castAction = new UCCFocus.Items.Actions.Magic.CastActions.DynamicSpawnProjectile();
castAction.SpellIndex = m_SpellIndex;
castAction.ProjectilePrefab = Resources.Load<GameObject>("Prefabs/Magic/Fireball") as GameObject;
castAction.Speed = projectile.velocity / 64f;
castAction.Initialize(m_Locomotion.gameObject, item, 0);

var actions = new System.Collections.Generic.List<Opsive.UltimateCharacterController.Items.Actions.Magic.CastActions.CastAction>();
actions.Add(castAction);

item.CastActions = actions.ToArray();

#endregion
 

Attachments

  • BadCastAction.png
    BadCastAction.png
    36.6 KB · Views: 6
Last edited:
A few bugs, requests and observations...

When using multiple 'Spawn Projectile' the Projectiles converge on the target point. Instead of converge, add checkbox to apply projectile offset to target point? For example, if 2 projectiles spaced 1 unit left and right of the cast point were shot at an enemy and the enemy is 1 unit in diameter. The projectiles would then pass by the enemy on the left and right.

When you cast and 'target' has no target, the player should still cast. For example, aiming at the sky that has no collider. Should never happen - the scene should have collider barriers.

If the spell requires a friendly target and the target is not friendly; play 'nocast' audio.

Magic Item > Use > Attributes > Use Attribute: Needs an array of attributes. For example, Power and Fatigue.
Added a ModifyAttribute CastAction. An attribute CastEvent is useful, but CanUse needs to fail if one or more of the attributes is depleted.

When required Attributes to cast are not available, play 'nocast' audio. Optionally, do not show cast animation. You can see this by using the ParticleStream with Mana per Use set to 8. Cast again quickly when you hit 0 to see the Cast animation attempts to start.

Magic Item > Magic: If you have not added any Begin, Cast, Impact or End Action the Cast still happens. Play 'nocast' audio?
Should never happen.

Magic Item > Magic > Use Type > Continuous: Wanted: Continuous with Animation? For example, cast Fireball one after another (with full animation) when the mouse is held down. Essentially, a looped Single cast.

First and Third person orientation is 90 degrees off.
  • Select Fireball on Nolan in the Magic room
  • Set the Position Offset of SpawnProjectile to (0, 1, 0)
  • Add a second duplicate Fireball CastAction with the Position Offset of (0, -1, 0)
  • Fire in First and Third to see the orientation changes. I would expect the same visual result in either Perspective.
If you set Fireball to Continuous, Continuous Duration to -1 and Continuous every Update is True. Hold mouse to start Continuous casting. You no longer can cast after releasing the mouse.
 
Last edited:
The inspector gets its list from the serialized CastAction data. Because the action is never being serialized it isn't going to show (not sure why it is showing as a selected element though).

I've merged this thread with your other thread and will refer to it when improving the magic items.
 
That makes sense - since it isn't being serialized the item doesn't know that it exists. I've added this thread to my todo list when I start to improve the magic item. This is exactly the feedback that I was looking for :)
 
I've figured out a way around the audio issue. I removed the Use audio and added a CastAction audio. I created a "dynamic" version of each of the CastAction that gives complete control of the audio within the Cast override. Switching the CastAction audio based on the Cast hit gives the desired result!
 
Just giving you a heads up that I am watching this - I haven't been able to work on improving magic items yet but when I do I'll definitely reference this thread.
 
I have UnityEngine.CharacterController working. If I want to call "m_MagicItem.PerformImpact()" from my custom impact script - it requires a RaycastHit.

Could you add a PerformImpact() overload that takes "ControllerColliderHit" as the hit param? This is an extensive request (impact actions,surface system,etc) or I would add it in my scripts.
 
Last edited:
Opsive.UltimateCharacterController.Items.Actions.Magic.CastActions.PhysicsCast.cs

There is no public MaxCollisionCount!

C#:
public int MaxCollisionCount { get { return m_MaxCollisionCount; } set { m_MaxCollisionCount = value; } }
 
Opsive.UltimateCharacterController.Items.Actions.Magic.CastActions.PhysicsCast.cs

There is no public MaxCollisionCount!

C#:
public int MaxCollisionCount { get { return m_MaxCollisionCount; } set { m_MaxCollisionCount = value; } }
This one is by design - MaxCollisionCount initializes an array so it should not be changed. You should always set it to the maximum possible value.
 
This one is by design - MaxCollisionCount initializes an array so it should not be changed. You should always set it to the maximum possible value.

If you are dynamically creating the PhysicsCast by code, how are you supposed to set the value? I def wouldn't want to use the default 50.

For example, if 10 NPC were standing in a line and you shot a ray at them - it would hit them all. One spell might have a max count of 1 and another might have a max of 3. The problem is "PerformImpact" is called on all the hits, so you must limit the max.

Note: I am using one MagicItem for ALL spells.

This might be ok for a static configuration that exists before runtime. In my case, the properties of MagicItem are being refreshed before each Use.
C#:
var physicsCast = new Opsive.UltimateCharacterController.Items.Actions.Magic.CastActions.PhysicsCast();
physicsCast.Distance = dispell.range / 64f;
physicsCast.Layers = LayerMask.GetMask("Wall");
physicsCast.MaxCollisionCount = 1;
physicsCast.TriggerInteraction = QueryTriggerInteraction.Collide;
physicsCast.Initialize(m_CharacterGO, m_MagicItem, 0);

castActions.Add(physicsCast);
 
Last edited:
The magic system is glorious! My first round with the Magic system is complete. Here is a final compilation of what I ran into...


Required SubClass
---------------------------------------------------------------

Opsive.UltimateCharacterController.Items.Actions.MagicItem.cs
  • It would be helpful to have a reference to the GameObject (or raycastHit) that determined the cast valid (within DetermineCastValues()).
Opsive.UltimateCharacterController.Items.Actions.Magic.CastActions.SpawnParticle.cs
  • It would be helpful to have the option of Parenting the SpawnParticle to the origin root. When moving while a SpawnParticle is parented does not look good - Parenting to the root looks good.
Opsive.UltimateCharacterController.Items.Actions.Magic.CastActions.PhysicsCast
  • m_MaxCollisionCount needs a public property.
Requires core changes
---------------------------------------------------------------

Opsive.UltimateCharacterController.Items.Actions.MagicItem.cs
  • Fix serialization
  • "Use Attribute" and "Character Use Attribute" should be an array to allow multiple Attribute use per cast.
  • Add PerformImpact() overload that has "ControllerColliderHit" param in place of "RayCastHit".
    • SubClass is not an option due to the amount of files this impacts.
Other
  • When using multiple 'Spawn Projectile' the Projectiles converge on the target point.
    • Instead of converge, add checkbox to apply projectile offset to target point?
    • For example, if 2 projectiles spaced 1 unit left and right of the cast point were shot at an enemy and the enemy is 1 unit in diameter. The projectiles would then pass by the enemy on the left and right.
  • First and Third person orientation is 90 degrees off.
    • Select Fireball on Nolan in the Magic room
    • Set the Position Offset of SpawnProjectile to (0, 1, 0)
    • Add a second duplicate Fireball CastAction with the Position Offset of (0, -1, 0)
    • Fire in First and Third to see the orientation changes. I would expect the same visual result in either Perspective.
  • Magic Item > Magic > Use Type > Continuous
    • Wanted: Continuous with Animation?
    • For example, cast Fireball one after another (with full animation) when the mouse is held down. Essentially, a looped Single cast.
 
Last edited:
Awesome - thank you for the writeup! I'll let you know when I start taking a look at MagicItem improvements.
 
Here is a scene that shows Magic Projectiles are not landing quite at the crosshairs. Where if you compare the same hit by the RightPistol - the RightPistol hits dead center of the crosshair. This is even more noticeable when using a much smaller (0.04) debug sphere.

I've noticed this on the PhysicsCast CastAbility when you add debug sphere's to the origin/hit.point. The hit.point seems always off to the bottom left. This ultimately effects everything, projectiles, etc.
 

Attachments

  • MagicAiming.unitypackage
    256.3 KB · Views: 2
When I try that scene this is what I get:

1591183987744.png

The reason why the projectile is slightly lower is because the projectile collider is larger than a point so it hits the floor before it can progress to the center of the crosshairs.
 
When using a smaller projectile/collider it is more pronounced - not closer to center. I'll work on a better example when magic is fixed.
 
Top