I created a code for Steam Achievements

#if UNITY_STANDALONE
using Steamworks;
using UnityEngine;

public class AchievementManager : MonoBehaviour
{
    // Our GameID
    private CGameID m_GameID;

    private bool tzompantliTested = false;
    private bool hasTzompantli= false;


    // Callback for Achievement stored
    protected Callback<UserAchievementStored_t> m_UserAchievementStored;

    public static AchievementManager instance = null;

    private Achievement[] Achievements = new Achievement[] {
        new Achievement(AchievementEnum.ACH_VAM_WIN, "La Mujer Vámpiro", ""),
        new Achievement(AchievementEnum.ACH_YOT_WIN, "Yotecatl", ""),
        new Achievement(AchievementEnum.ACH_DRA_WIN, "Drakenhaussen", ""),
        new Achievement(AchievementEnum.ACH_KIT_WIN, "Kitty", ""),
        new Achievement(AchievementEnum.ACH_FAU_WIN, "El Fausto", ""),
        new Achievement(AchievementEnum.ACH_PIS_WIN, "Piscuario", ""),
        new Achievement(AchievementEnum.ACH_CHA_WIN, "Charro Negro", ""),
        new Achievement(AchievementEnum.ACH_LLO_WIN, "Llorona", ""),
        new Achievement(AchievementEnum.ACH_PEN_WIN, "Penumbra", ""),
        new Achievement(AchievementEnum.ACH_LUZ_WIN, "Luzbelle", ""),
        new Achievement(AchievementEnum.ACH_VAM_CHA, "Challenge mujer vampiro", ""),
        new Achievement(AchievementEnum.ACH_YOT_CHA, "Challenge Yotecatl", ""),
        new Achievement(AchievementEnum.ACH_DRA_CHA, "Challenge Drakkenhaussen", ""),
        new Achievement(AchievementEnum.ACH_KIT_CHA, "Challenge Kitty", ""),
        new Achievement(AchievementEnum.ACH_FAU_CHA, "Challenge Fausto", ""),
        new Achievement(AchievementEnum.ACH_PIS_CHA, "Challenge Piscuario", ""),
        new Achievement(AchievementEnum.ACH_CHA_CHA, "Challenge Charro", ""),
        new Achievement(AchievementEnum.ACH_LLO_CHA, "Challenge Llorona", ""),
        new Achievement(AchievementEnum.ACH_PEN_CHA, "Challenge Penumbra", ""),
        new Achievement(AchievementEnum.ACH_LUZ_CHA, "Challenge Luzbelle", ""),
        new Achievement(AchievementEnum.ACH_VS_COUNT, "Contador vs", ""),
        new Achievement(AchievementEnum.ACH_ONLINE_COUNT, "Contador Online", ""),
        new Achievement(AchievementEnum.ACH_MOS_COUNT, "Contador Mostro", ""),
        new Achievement(AchievementEnum.ACH_ESC_COUNT, "Contador Escapes", ""),
        new Achievement(AchievementEnum.ACH_COUNT_COUNT, "ContadorCounter", ""),    
        new Achievement(AchievementEnum.ACH_3D, "3D BABY", ""),    
        
    };


    //La clase Achievement es un POJO que encapsula algunas propiedades del logro
    public class Achievement
    {
        public AchievementEnum AchievementID;
        public string Name;
        public string Description;
        public bool Achieved;

        ///
        /// Creates an Achievement. You must also mirror the data provided here in [url]https://partner.steamgames.com/apps/achievements/yourappid[/url]
        ///
        /// The "API Name Progress Stat" used to uniquely identify the achievement.
        /// The "Display Name" that will be shown to players in game and on the Steam Community.
        /// The "Description" that will be shown to players in game and on the Steam Community.
        public Achievement(AchievementEnum achievementID, string name, string desc)
        {
            AchievementID = achievementID;
            Name = name;
            Description = desc;
            Achieved = false;
        }
    }

    // Un simple Enum con los logros correspondientes
    public enum AchievementEnum : int
    {
        ACH_VAM_WIN,
        ACH_YOT_WIN,
        ACH_DRA_WIN,
        ACH_KIT_WIN,
        ACH_FAU_WIN,
        ACH_PIS_WIN,
        ACH_CHA_WIN,
        ACH_LLO_WIN,
        ACH_PEN_WIN,
        ACH_LUZ_WIN,
        ACH_VAM_CHA,
        ACH_YOT_CHA,
        ACH_DRA_CHA,
        ACH_KIT_CHA,
        ACH_FAU_CHA,
        ACH_PIS_CHA,
        ACH_CHA_CHA,
        ACH_LLO_CHA,
        ACH_PEN_CHA,
        ACH_LUZ_CHA,
        ACH_VS_COUNT,
        ACH_ONLINE_COUNT,
        ACH_MOS_COUNT,
        ACH_ESC_COUNT,
        ACH_COUNT_COUNT,
        ACH_3D
    }


    // Use this for initialization
    void Start()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(gameObject);
        }

        DontDestroyOnLoad(gameObject);

        //DebugAchievements();
    }

    private void DebugAchievements()
    {
        if (SteamManager.Initialized)
        {
            Debug.Log("SteamManager initialized.");

            // Cache the GameID for use in the Callbacks
            m_GameID = new CGameID(SteamUtils.GetAppID());
            m_UserAchievementStored = Callback<UserAchievementStored_t>.Create(OnAchievementStored);
            PrintAchievements();
        }
        else
        {
            Debug.LogWarning("SteamManager NOT initialized!");
        }
    }

    private void PrintAchievements()
    {
        foreach (Achievement ach in Achievements)
        {
            bool ret = SteamUserStats.GetAchievement(ach.AchievementID.ToString(), out ach.Achieved);
            if (ret)
            {
                ach.Name = SteamUserStats.GetAchievementDisplayAttribute(ach.AchievementID.ToString(), "name");
                ach.Description = SteamUserStats.GetAchievementDisplayAttribute(ach.AchievementID.ToString(), "desc");

                Debug.LogFormat("Achievement Name: {0} --- Unlocked: {1}", ach.Name, ach.Achieved);
            }
            else
            {
                Debug.LogWarning("SteamUserStats.GetAchievement failed for Achievement " + ach.AchievementID + "\nIs it registered in the Steam Partner site?");
            }
        }
    }

    ///
    /// Calls SetAchiemement. Steam docs:
    /// This method sets a given achievement to achieved and sends the results to Steam. You can set a given achievement multiple times so you don't
    /// need to worry about only setting achievements that aren't already set.
    /// This is an asynchronous call which will trigger two callbacks: OnUserStatsStored() and OnAchievementStored()
    ///
    ///
    public void UnlockAchievement(AchievementEnum achievement)
    {
        SteamUserStats.SetAchievement(achievement.ToString());
        SteamUserStats.StoreStats();
    }
    
        public void EraseAchivement()
    {
        SteamUserStats.ResetAllStats(true);
    }

    public bool unlockTzompantliCharacter()
    {
        //542240  574980
        AppId_t TzompantliID = new AppId_t(542240);

        if (!tzompantliTested)
        {
            hasTzompantli = SteamApps.BIsSubscribedApp(TzompantliID);

            if(hasTzompantli)
                Debug.Log("Si compró Tzompantli, ya tiene nuevo mona!");
            else
                Debug.Log("No compró Tzompantli");
            tzompantliTested = true;
        }



        return hasTzompantli;
    }


        //-----------------------------------------------------------------------------
        // Purpose: An achievement was stored
        //-----------------------------------------------------------------------------
        public void OnAchievementStored(UserAchievementStored_t pCallback)
    {
        // We may get callbacks for other games' stats arriving, ignore them
        if ((ulong)m_GameID == pCallback.m_nGameID)
        {
            if (0 == pCallback.m_nMaxProgress)
            {
                Debug.Log("Achievement '" + pCallback.m_rgchAchievementName + "' unlocked!");
            }
            else
            {
                Debug.Log("Achievement '" + pCallback.m_rgchAchievementName + "' progress callback, (" + pCallback.m_nCurProgress + "," + pCallback.m_nMaxProgress + ")");
            }
        }
    }
}

#endif

It has worked so far, but just when I try to add a code to call it from ChallengeMode.cs

AchievementManager.instance.UnlockAchievement(AchievementManager.AchievementEnum.ACH_VAM_CHA);
                    break;

it sends me a message

Assets\UFE\Engine\Scripts\Core\Manager\ChallengeMode.cs(167,21): error CS0103: The name 'AchievementManager' does not exist in the current context

I can make that simple line of code to run from defaultBattleGUI.cs with no issues, but not from ChallengeMode.cs, someone knows what I'm doing wrong? thank you

Hello,
I'm a little rusty with this old code, but by error it seems that you didin't add the altButton variable in the inputOptions class in the globalInfo.cs file.

It's the fifth code in the post.

I hope that's the reason for your error.

If you have any other issue just tell me.

Also, this code is for UFE 1.x The 2.x version needs some corrections, I dont know if I wrote a post about it too.

diesonblack22 wrote:

in the default selection screen i dont see the

bool p2AxisDown =
            p2InputController.GetButtonDown(p2InputController.horizontalAxis) ||
            p2InputController.GetButtonDown(p2InputController.verticalAxis);


Yes, I just remembered that for some reason we've been unable to update our game to the news libraries of UFE, in the new version that code doesn't exist, I just Downloaded the new version of UFE and edited the post to reflect this, sorry

really love the idea of a game of MOTU, much more if is a Fighting Game, hope you can publish more of this soon.

I wrote this code some time ago Because when my brother taught me how movesets and character models worked on UFE my first thought was" that should make easy to create characters with multiple costumes", but when he told me UFE hadn't implemented that I make the commitment to myself that I should do it for our Game Tzompantli. So I already did it some months ago, but did not have time to post it until now, here it is the way I made the alternate costumes work on UFE.


First

on CharacterInfo.cs just add

public GameObject alternateCharacterPrefab; 

after

public GameObject characterPrefab;

Now add

public bool alternativeCostume = false;

after

public string characterDescription;

Thats all on CharacterInfo.cs, now we can go to GlobalInfo.cs and do a minor change

add the variable

public ButtonPress altButton;

In the  InputOptions class.
Now for easy use we are going to give us access to those variables throught the Edition window, to make that happen we are going to change  CharacterEditorWindow.cs and add

characterInfo.alternateCharacterPrefab = (GameObject) EditorGUILayout.ObjectField("Character Alt Prefab:", characterInfo.alternateCharacterPrefab, typeof(UnityEngine.GameObject), true);

after

characterInfo.characterPrefab = (GameObject) EditorGUILayout.ObjectField("Character Prefab:", characterInfo.characterPrefab, typeof(UnityEngine.GameObject), true);

Now in GlobalEditorWindow.cs add

globalInfo.inputOptions.altButton = (ButtonPress) EditorGUILayout.EnumPopup("Alt Button:", globalInfo.inputOptions.altButton, enumStyle);
after this line
globalInfo.inputOptions.cancelButton = (ButtonPress) EditorGUILayout.EnumPopup("Cancel Button:", globalInfo.inputOptions.cancelButton, enumStyle);

after this if you go to the global editor window on Unity this new option will appear
http://sagapodcast.com/blog/wp-content/uploads/2016/06/IMG_0467.jpg

And in the character editor will look like this
http://sagapodcast.com/blog/wp-content/uploads/2016/06/IMG_0468.jpg

Now we can go to the last part of this simple tutorial and make the game chose the costume we want, as you can imagine, in the altButton option in the input options that  you now have in your global editor you must choose a button that when pressed will set the option to load the alternateCharacterPrefab when the variable alternativeCostume is true, so after you add an alternate character prefab to your character and choose the button you want to use to select the alternate costume function we will write the rest of the code.

Now in controlsScript.cs in the start function after

if (myInfo.characterPrefab == null) 
            Debug.LogError("Character prefab for "+ gameObject.name +" not found. Make sure you have selected a prefab character in the Character Editor");

Add these lines

        
//JUST A DEBUG FOR CHECKING HOW IS WORKING ALL
Debug.Log ("ControlScript,Player:"+playerNum+"Alternate Costume Value:" + myInfo.alternativeCostume);
        if (myInfo.alternativeCostume) {
            if (myInfo.alternateCharacterPrefab == null)
            {
                character = (GameObject)Instantiate (myInfo.characterPrefab);
                Debug.Log("Character prefab for "+ gameObject.name +"The Character Doesn't Have Alternate Costume. Make sure you have selected a prefab character in the Character Editor");
            }
            else
                character = (GameObject)Instantiate (myInfo.alternateCharacterPrefab);
        } else {
            character = (GameObject)Instantiate (myInfo.characterPrefab);
        }

As you can see, the code changes the default character loading behavior so if the alternativeCostume variable is true it will load the alternative prefab we added to the character info, in any case there were an error and the character doesn't have a alternate costume, the game will load the regular one, so you  don't have to give al characters an alternative costume if you don't want.

Now in CharacterSelectionScreen.cs let's add this lines to the OnCharacterSelectionAllowed

after

if (character != null && character.selectionSound != null) UFE.PlaySound(character.selectionSound);

add this

                    if((player == 1 && this.p1AltCustom==true) || (player == 2 && this.p2AltCustom==true))
                    { 
                        character.alternativeCostume=true;
                    }
                    else
                    {
                        character.alternativeCostume=false;
                    }
                                        //I really like to send debugs  
                    Debug.Log("Character Select,Player "+player+" alternate:"+character.alternativeCostume);

and after

protected int p2HoverIndex = 0;

You must add

protected bool p1AltCustom=false;
protected bool p2AltCustom=false;

The last bit of code is to be able to put in true or false the p1AltCustom or p2AltCustom, so in DefaultCharacterSelectionScreen.cs on the doFixedUpdate function after:

base.DoFixedUpdate();

just add:

if(p1InputController.GetButtonDown(UFE.config.inputOptions.altButton)){

            this.p1AltCustom =!(this.p1AltCustom);
            Debug.Log("Boton Alterno player 1:"+this.p1AltCustom);
            //this.TrySelectCharacter(this.p1HoverIndex, 1);
            
        }
        if(p2InputController.GetButtonDown(UFE.config.inputOptions.altButton)){
            this.p2AltCustom =!(this.p2AltCustom);
            Debug.Log("Boton Alterno player 2:"+this.p2AltCustom);
            //this.TrySelectCharacter(this.p1HoverIndex, 1);
            
        }

So, that's all, you now can make alternate Costumes for your characters in the way the first Soul Blade or Tekken Worked, some warnings, I never added a little window or something on the character selection screen so it show the player if he/she es choosing the regular or alternate costume, I have had no time for it yet, if I make it I will add it to this post.

Second, I know and figured out that if we could change the  alternateCharacterPrefab and characterPrefab to merge them in one characterPrefab[] (an array) and make some modifications to this code we can simply have infinity and variable alternate costumes for any character, like in Dead or Alive where the female characters have like 15 costumes and male characters have only 2, but I'll try it for the next game we make but if anyone wants to give a try just post it so everyone here can use it.

Last, the characters need to have the same bone structure, so the animations can run correctly, also you can add functionality so characters on alternate costumes can perform an alternate fighting intro animation, but I'm just talking nonsense.

Thank you and I hope anyone can use this options and doubts and complain are accepted by DM or twitter @seekerofpower

I only have this video from when I finished the script
https://www.facebook.com/seekerofpower/ … 8122777617

But I will ask mi brother if he can upload to youtube one nicer looking, sorry for my english

My Brother StridrSpinel noticed that when useSameStoryForAllCharacters is off UFE always selects the Story of the fisrt Character on the list of characters and not the One Selected, so for a few hours dedicated to search for this error and found a solution and I share it to anyone who has this issue


On UFE.cs change

public static CharacterStory GetCharacterStory(CharacterInfo character){
        if (!UFE.config.storyMode.useSameStoryForAllCharacters){
            for (int i = 0; i < UFE.config.characters.Length; ++i){
                int index = UFE.config.storyMode.selectableCharactersInStoryMode.IndexOf(i);
                //CHANGE THIS IF
                if (UFE.config.characters[i] != null && index >= 0){
                    
                   //CHANGE THIS RETURN   
                   return UFE.config.storyMode.characterStories[index];
                }
            }
        }
        
        return UFE.config.storyMode.defaultStory;
    }

public static CharacterStory GetCharacterStory(CharacterInfo character){
        if (!UFE.config.storyMode.useSameStoryForAllCharacters){
            for (int i = 0; i < UFE.config.characters.Length; ++i){
                int index = UFE.config.storyMode.selectableCharactersInStoryMode.IndexOf(i);
                // NEW IF ADDS CHARACTER COMPARISON 
                if (UFE.config.characters != null && (UFE.config.characters[i].name+"(Clone)")==character.name && index >= 0){
                    // NEW RETURN SENDS THE CORRECT INDEX
                     return UFE.config.storyMode.characterStories[i];
                }
            }
        }
        
        return UFE.config.storyMode.defaultStory;
    }

So now the correct storycharacter Story is selected, I hope It could hepfull no everyone

Just Writing to keep my post on the top so someone can help me

Hello.

I'm trying to make a character glow like they glow when the character makes a parry but now when my character is making a move and the attack has armor.

I tried this from what I know

on BattleGUI.cs  inside OnHit

if (move.armorOptions.hitAbsorption > 0) {
            Debug.Log ("Armor");

            int Player = player == this.player1.character ? 1 : 2;
            ControlsScript armorControlsScript=UFE.GetControlsScript(Player);
            UFE.config.blockOptions.parryColor = Color.green;

            armorControlsScript.HighlightOn(armorControlsScript.gameObject,true);

But sometimes it sends me this error


NullReferenceException: Object reference not set to an instance of an object
BattleGUI.OnHit (.HitBox strokeHitBox, .MoveInfo move, .CharacterInfo player) (at Assets/UFE/Scripts/UI/Base/BattleGUI.cs:143)
UFE.FireHit (.HitBox strokeHitBox, .MoveInfo move, .CharacterInfo player) (at Assets/UFE/Scripts/UFE.cs:1181)
ControlsScript.GetHit (.Hit hit, Int32 remainingFrames, Vector3 location) (at Assets/UFE/Scripts/ControlsScript.cs:1951)
ProjectileMoveScript.DoFixedUpdate () (at Assets/UFE/Scripts/ProjectileMoveScript.cs:204)
UFE.FixedUpdate () (at Assets/UFE/Scripts/UFE.cs:1658)

Can someone give a hint about what am I doing wrong?

Thanks you for your help

9

(10 replies, posted in UFE 1 (Deprecated))

ralph wrote:

Not sure if you guys caught this, but there is an issue with Linq on iOS (used in the AI). I used UniLinq (can easily find on GitHub).

AI was unresponsive without making the change, but I assumed you guys have fixed it (still running 1.5 for the time being).



I just tried the Unilinq library on my project and my app on iOS is working smootly, thank yoou very much for the tip, you saved my life

10

(10 replies, posted in UFE 1 (Deprecated))

Well I tried to change the MoveInfo.cs to add the 'Mid' HitType and try to correct the error, but six more appear on it's place.

Sorry, to botter, but are you sure this is the last version that you're going to put in the asset store, By the way we're  still working with UFE 1.5 and  Unity 4.6.5

11

(10 replies, posted in UFE 1 (Deprecated))

Sorry I just installed the new version of Fuzzy AI that you shared to Strider Spinel, but the new versionshows me this error message

Assets/UFE Addons/Fuzzy AI/Runtime/AIInfo.cs(348,139): error CS0117: `HitType' does not contain a definition for `Mid'

Could you tell me mr mastermind what to do to prevent this error?

Thank you for your time