This document is about: FUSION 2
SWITCH TO

Extending

Partial Implementation

Extending the KCC addon via partial class implementation is a powerful technique that allows you to enhance the functionality of existing classes without modifying their original source code. Simply create a new Class.Feature.cs or Class.Game.cs file and write your logic. This makes addon update process much easier and keeps your project organized.

Following sections exemplify how to extend existing classes.

Extending KCC

Create a file KCC.Sprint.cs with following implementation:

C#

namespace Fusion.KCC
{
    public partial class KCC
    {
        public void SetSprint(bool sprint)
        {
            Data.Sprint = sprint;
        }
    }
}

Extending KCCData

Create a file KCCData.Sprint.cs with following implementation:

C#

namespace Fusion.KCC
{
    public partial class KCCData
    {
        public bool Sprint;

        partial void CopyUserDataFromOther(KCCData other)
        {
            // Making a deep copy for correct rollback from local history.
            // This method is executed when you get a new state from server.
            // It is also executed after fixed updates to copy fixed data to render data.

            Sprint = other.Sprint;

            // Because this method is partial and cannot be implemented for each property separately, you have to copy all properties here.
            // Or use this method as a wrapper and split execution into multiple calls.
        }
    }
}

⚠️ Every property added to KCCData must be also added to partial void CopyUserDataFromOther(KCCData other), otherwise it won't work correctly.

Extending KCCSettings

Create a file KCCSettings.CustomProperty.cs with following implementation:

C#

namespace Fusion.KCC
{
    public partial class KCCSettings
    {
        public bool CustomProperty;

        partial void CopyUserSettingsFromOther(KCCSettings other)
        {
            // Make a deep copy of your properties.
            // This method is also executed on spawn/despawn to store/restore backup.
            CustomProperty = other.CustomProperty;

            // Because this method is partial and cannot be implemented for each property separately, you have to copy all properties here.
            // Or use this method as a wrapper and split execution into multiple calls.
        }
    }
}

⚠️ Every property added to KCCSettings must be also added to partial void CopyUserDataFromOther(KCCSettings other), otherwise it won't work correctly.

Extending KCCInteraction and KCCInteractions

Create a file KCCInteractions.Game.cs with following implementation:

C#

namespace Fusion.KCC
{
    // Returns HUD information from interactions for displaying on screen.
    public interface IHUDProvider
    {
        string Description { get; }
    }

    // KCCInteraction is a container which contains information related to single interaction.
    // KCCInteraction is abstract class, extending it also affects derived classes (all other interaction container types).
    public abstract partial class KCCInteraction<TInteraction>
    {
        // This instance is pooled, only stateless getters!

        public IHUDProvider HUDProvider => Provider as IHUDProvider;
    }

    // KCCInteractions is a collection which maintains all interactions.
    // KCCInteractions is abstract class, extending it also extends derived classes (all other interaction collection types).
    public abstract partial class KCCInteractions<TInteraction>
    {
        // You can iterate over All property and apply custom filtering.

        public T GetHUDProvider<T>() where T : IHUDProvider
        {
            for (int i = 0, count = All.Count; i < count; ++i)
            {
                if (All[i].HUDProvider is T hudProvider)
                    return hudProvider;
            }

            return default;
        }
    }
}

Extending KCCCollision and KCCCollisions

Create a file KCCCollisions.Game.cs with following implementation:

C#

namespace Fusion.KCC
{
    using UnityEngine;

    // Returns climb information from networked collisions.
    public interface IClimbProvider
    {
        Transform Target { get; }
    }

    // KCCCollision is a container which contains information related to a single networked collision.
    public partial class KCCCollision
    {
        // This instance is pooled, only stateless getters!

        public IClimbProvider ClimbProvider => Processor as IClimbProvider;
    }

    // KCCCollisions is a collection which maintains all networked collisions.
    public partial class KCCCollisions
    {
        // You can iterate over All property and apply custom filtering.

        // Example: returns first climb provider of a specific type.
        public T GetClimbProvider<T>() where T : IClimbProvider
        {
            for (int i = 0, count = All.Count; i < count; ++i)
            {
                if (All[i].ClimbProvider is T climbProvider)
                    return climbProvider;
            }

            return default;
        }
    }
}

Extending KCCModifier and KCCModifiers

An example using existing type defined outside:

C#

namespace Game
{
    // Base interface for all abilities.
    public interface IAbility
    {
        // ...
    }
}

Create a file KCCModifiers.Game.cs with following implementation:

C#

namespace Fusion.KCC
{
    using System.Collections.Generic;
    using Game;

    // KCCModifier is a container which contains information related to single modifier.
    public partial class KCCModifier
    {
        // This instance is pooled, only stateless getters!

        public IAbility Ability => Processor as IAbility;
    }

    // KCCModifiers is a collection which maintains all modifiers.
    public partial class KCCModifiers
    {
        // You can iterate over All property and apply custom filter.

        // Example: returns list of abilities of a specific type.
        public bool GetAbilities<T>(List<T> abilities) where T : IAbility
        {
            abilities.Clear();

            for (int i = 0, count = All.Count; i < count; ++i)
            {
                if (All[i].Ability is T ability)
                {
                    abilities.Add(ability);
                }
            }

            return abilities.Count > 0;
        }
    }
}
Back to top