Announcement

Collapse
No announcement yet.

(Illusion) PlayHome Trial & Game (プレイホーム) - Modding Discussion

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • [Mod Discussion] (Illusion) PlayHome Trial & Game (プレイホーム) - Modding Discussion

    Please discuss how to mod the trial & game here.

    As long as there is no separate subforum for PH you can also discuss problems with mods here.

    Useful links:
    Last edited by enimaroah; 04-22-2018, 12:39 PM.

  • #16
    Oh good grief ... is there anything Sb3UGS can't do?

    I was about to start doing a crap load of logging to see how the cameras are built but this looks better!
    Hopefully I can "fix" stuff all in (easier for me to understand) C# plugin code. I'm not ready to understand what "create a new virtual Animator" means.

    One of these days I'm going to understand this stuff.

    Thanks enimaroah ... thanks plasticmind!

    Comment


    • #17
      I had tried to display the most interesting assets in files, even sounds. Animations are currently missing, but I will close that gap later.

      The name Animator has a slightly different meaning in Sb3UGS than in Unity for historical reasons. It is close to what Prefabs are. In regular game files there is no AssetBundle asset, in which Prefabs are stored. So Sb3UGS shows only real Animator assets in the Animator tab. And in all files these are the handles for opening all assets of that Prefab. When real Animator assets are not present then Sb3UGS looks for prefab entries in the AssetBundle asset and creates Animator assets just as a handle; those are not really present in the file, and therefore I called them virtual Animators. In regular game files which have no AssetBundle asset and without real Animator assets Sb3UGS cant show any Animator, but it allows to create virtual Animators where ever GameObject assets are. GameObject assets are hidden by default. So you have to uncheck "Filter Included Assets" to make them visible.

      Comment


      • akoybobo
        akoybobo commented
        Editing a comment
        *nods head like he understands*

    • #18
      To get a better understanding, I would suggest to create a mini project in Unity editor (version 5.5.4) with a MonoBehaviour (and a hosting GameObject). Something like this:
      Spoiler
      Code:
      using UnityEngine;
      using System.Collections;
      
      public class Structure : MonoBehaviour {
      
          public RuntimeAnimatorController abc;
          public int[] some_values = new int[2] { 5, 852 };
      
          // Use this for initialization
          void Start () {
      
              some_values [0]++;
          }
      
          // Update is called once per frame
          void Update () {
      
              some_values [1]--;
          }
      }

      Build the project and inspect the files with Sb3UGS. Then learn to create AssetBundle files and put your MonoBehaviour into one. This will clear up what MonoScript, MonoBehaviour, Animator and AssetBundle assets are and how those are linked together.

      Comment


      • akoybobo
        akoybobo commented
        Editing a comment
        Sincerely appreciate the pointers!

    • #19
      Yay!

      Clipping is fixed. It was indeed the nearCliplane but I had to change how the camera was defined. And then that broke it.
      Ended up having to change part of the VRGIN library itself to turn off copying skyboxes and the renderpath from the non-VR camera otherwise the VR camera can't see squat.


      Click image for larger version

Name:	20170830074003_1_vr.jpg
Views:	1
Size:	97.8 KB
ID:	5818672Click image for larger version

Name:	20170830074017_1_vr.jpg
Views:	1
Size:	114.0 KB
ID:	5818673


      Once I got that all working ... VRGIN already does roomscale. Nothing for me to do for that. It just worked like it's supposed to. (Love you Eusth)

      Click image for larger version

Name:	20170830073950_1.jpg
Views:	1
Size:	421.5 KB
ID:	5818674


      Now the hard part. Figuring out if the fancy shaders, materials, effects, etc can be worked out.

      Comment


      • v555
        v555 commented
        Editing a comment
        wondering if the download on mod releases has the clipping issue fixed? what would the purpose of this kind of near clipping (?) be used for... I understand for environments and such but for character models?

    • #20
      k, so i've made the girls climax! but... uh... i need to mod the assembly... i don't have a patcher to do so...
      i believe patchers like reipatcher do only basics? like... uh.. insert methods call inside functions and
      not advanced stuffs like replace a whole method marked as [MethodImpl(MethodImplOptions.InternalCall)]
      ppl like Eusth (IPA creator) are writing their own patcher... i've started mine but it takes forever to make a fully functional one...
      so, what patcher options are you guys using?
      Attached Files
      Last edited by akyryz; 09-01-2017, 04:18 AM.
      Creator and maintainer of UI Translation Loader
      An assets replacer for Unity engine focused on translation

      Comment


      • akoybobo
        akoybobo commented
        Editing a comment
        You might already know but Eusth puts all of his source on GitHub.

        It would be great to make fork of IPA if there are features you want to add to it and don't mind sharing.

        https://github.com/Eusth/IPA

    • #21
      The correction of the UVNormalBlend MonoBehaviour is nearly done and it works similar to the Nml MB computation. During implementation I found an error for unwelded meshes which needs to be fixed for Nml MBs.

      Here in the PH demo is a strange situation for Nml MBs and UVNormalBlend MBs. Three tops (ending with ph) have no Nml MBs, but their UVNormalBlend MBs use the correction for normals and UVs. The other tops have UVNormalBlend MBs for correction of the normals only, the UVs are missing. But the same tops have Nml MBs for normals correction. And Nml MBs can correct only normals not UVs. Finally for the body there is an Nml MB, and for the tikubi meshes there is a UVNormalBlend MB with normals and UVs (plus an extra UVData MB which is unsupported by Sb3UGS).

      For this reason I will leave the gui of the Nml MB computation as it is. And I made an extra gui for the UVNormalBlend MBs. Should Illusion use both MB types then the modder will have to correct them independently and in two steps.
      Attached Files

      Comment


      • #22
        enimaroah

        I found some stuff that might be of some use. Not sure, they're all parameters for heads:

        Code:
        public class HeadParameter : ParameterBase
            {
        public int headID;
        
        public int faceTexID;
        
        public int detailID;
        
        public int eyeBrowID;
        
        public int eyeID_L;
        
        public int eyeID_R;
                ...
            }
        It seems that heads still have an ID. Maybe this ID is inside one of the three MonoBehaviours right below the first transform?

        There's also the MonoBs inside stuff that uses alpha channels, like cf_O_eyehikari_L, which is just SetRenderQueue.
        My blog, you can find my mods there too.

        Comment


        • #23
          Originally posted by enimaroah View Post
          enimaroah

          I found some stuff that might be of some use. Not sure, they're all parameters for heads:

          Code:
          public class HeadParameter : ParameterBase
          {
          public int headID;
          
          public int faceTexID;
          
          public int detailID;
          
          public int eyeBrowID;
          
          public int eyeID_L;
          
          public int eyeID_R;
          ...
          }
          It seems that heads still have an ID. Maybe this ID is inside one of the three MonoBehaviours right below the first transform?

          There's also the MonoBs inside stuff that uses alpha channels, like cf_O_eyehikari_L, which is just SetRenderQueue.

          In Trail, the IDs of the head is hardcoded in the game rather than the external list (the number in red).
          If the illusion doesn`t change this solution in release version, maybe you need to code a plugin or patcher to add your oringinal head IDs in the game.
          Code:
          HeadData[] array = new HeadData[]
          {
              new HeadData(0, "ヘッドA01", "FemaleHead_A1", 0),
              new HeadData(2, "ヘッドA02", "FemaleHead_A2", 1),
              new HeadData(3, "ヘッドA03", "FemaleHead_A3", 2),
              new HeadData(1, "ヘッドB", "FemaleHead_B", 3)
          };
          // located in CustomDataManager.Setup()
          Last edited by lwlin; 09-07-2017, 12:08 AM.

          Comment


          • #24
            Thanks lwlin for your investigation!

            I see this like you.

            roy12:
            The MBs seem to have other functions. See the names of their MonoScripts:
            Click image for larger version

Name:	HeadMBsAtAnimatorRoot.jpg
Views:	1
Size:	199.2 KB
ID:	5819916

            Comment


            • #25
              Originally posted by lwlin View Post


              In Trail, the IDs of the head is hardcoded in the game rather than the external list (the number in red).
              If the illusion doesn`t change this solution in release version, maybe you need to code a plugin or patcher to add your oringinal head IDs in the game.
              Code:
              HeadData[] array = new HeadData[]
              {
              new HeadData(0, "ヘッドA01", "FemaleHead_A1", 0),
              new HeadData(2, "ヘッドA02", "FemaleHead_A2", 1),
              new HeadData(3, "ヘッドA03", "FemaleHead_A3", 2),
              new HeadData(1, "ヘッドB", "FemaleHead_B", 3)
              };
              // located in CustomDataManager.Setup()
              Well, that sucks. Pretty sure the final game won't load them with lists either. I guess either a patcher or a plugin is in order. But still no idea of how to load them from another asset bundle that isn't the main one. Things might get messy.

              enimaroah

              Ah, sorry about that, now that I see the names of the MonoBs I know what to look for.

              AnimeLipSync:

              Code:
              public class AnimeLipSync : MonoBehaviour
              {
              public AudioSource audio;
              
                  [SerializeField]
              protected Animator animator;
              
                  [SerializeField]
              protected int layerNo;
              
                  [SerializeField]
              protected string blendName = "Blend";
              
                  [SerializeField]
              protected string speedName = "Speed";
              
                  [SerializeField]
              protected float lipSpeed = 1f;
              
              protected AudioVolumeAnalyzer analyser;
              
              protected float prevVol;
              
                  [SerializeField]
              protected float volMul = 1f;
              
                  [SerializeField]
              protected AnimationCurve volToMouth;
              
                  [SerializeField]
              protected LogLine volumeLine;
              
                  [SerializeField]
              protected LogLine blendLine;
              
                  [SerializeField]
              protected LogLine rawLine;
              
              public float RelaxOpen
                  {
              get;
              set;
                  }
              
              public bool Hold
                  {
              get;
              set;
                  }
              
              public virtual void Awake()
                  {
              this.analyser = new AudioVolumeAnalyzer();
              this.analyser.SetAudio(this.audio);
                  }
              
              public virtual void Update()
                  {
              float num = 0f;
              float num2 = 0f;
              if (!this.Hold)
                      {
                          num = this.analyser.AnalyzeSound(0.1f);
                          num2 = this.analyser.AnalyzeSound(0f);
                      }
              float time = num * this.volMul;
              float num3 = this.volToMouth.Evaluate(time);
              float num4 = Mathf.Abs(this.prevVol - num2);
              float value = Mathf.Clamp01(num4 * this.lipSpeed);
              this.animator.SetLayerWeight(this.layerNo, num3);
              this.animator.SetFloat(this.speedName, value);
              float value2 = Mathf.Lerp(0f, this.RelaxOpen, 1f - num3);
              this.animator.SetFloat(this.blendName, value2);
              float value3 = this.analyser.AnalyzeSound(0f);
              if (this.volumeLine)
                      {
              this.volumeLine.Add(num);
                      }
              if (this.blendLine)
                      {
              this.blendLine.Add(num3);
                      }
              if (this.rawLine)
                      {
              this.rawLine.Add(value3);
                      }
              this.prevVol = num2;
                  }
              }
              AnimeParamBlink:

              Code:
              public class AnimeParamBlink : MonoBehaviour
              {
                  [SerializeField]
              protected Animator animator;
              
                  [SerializeField]
              protected string paramName;
              
                  [SerializeField]
              protected AnimationCurve normalCurves;
              
                  [SerializeField]
              protected AnimationCurve rareCurves;
              
                  [SerializeField]
              protected float rareProbability = 10f;
              
                  [SerializeField]
              protected float speed = 1f;
              
                  [SerializeField]
              protected float waitMin = 2f;
              
                  [SerializeField]
              protected float waitMax = 5f;
              
              protected float timer;
              
              protected float blinkEvaluate;
              
              protected AnimationCurve useCurve;
              
              protected int paramID;
              
              protected float limitMin;
              
              protected float limitMax = 1f;
              
              public float LimitMin
                  {
              get
                      {
              return this.limitMin;
                      }
              set
                      {
              this.limitMin = value;
              this.UpdateParam();
                      }
                  }
              
              public float LimitMax
                  {
              get
                      {
              return this.limitMax;
                      }
              set
                      {
              this.limitMax = value;
              this.UpdateParam();
                      }
                  }
              
              public bool Hold
                  {
              get;
              set;
                  }
              
              public virtual void Awake()
                  {
              this.paramID = Animator.StringToHash(this.paramName);
              this.timer = UnityEngine.Random.Range(this.waitMin, this.waitMax);
              this.blinkEvaluate = 0f;
              this.useCurve = this.normalCurves;
                  }
              
              public virtual void Start()
                  {
              this.animator.SetFloat(this.paramID, this.limitMax);
                  }
              
              public virtual void Update()
                  {
              if (this.timer > 0f)
                      {
              if (!this.Hold)
                          {
              this.timer -= Time.deltaTime;
                          }
              if (this.timer <= 0f)
                          {
              this.useCurve = ((UnityEngine.Random.Range(0f, 100f) >= this.rareProbability) ? this.normalCurves : this.rareCurves);
              this.blinkEvaluate = 0f;
                          }
                      }
              else
                      {
              float num = 1f;
              if (this.blinkEvaluate < 1f)
                          {
              this.blinkEvaluate += Time.deltaTime * this.speed;
                              num = this.useCurve.Evaluate(this.blinkEvaluate);
                          }
              else
                          {
              this.timer = UnityEngine.Random.Range(this.waitMin, this.waitMax);
                          }
                          num = Mathf.Lerp(this.limitMin, this.limitMax, num);
              this.animator.SetFloat(this.paramID, num);
                      }
                  }
              
              public virtual void UpdateParam()
                  {
              float num = 1f;
              if (this.blinkEvaluate < 1f)
                      {
                          num = this.useCurve.Evaluate(this.blinkEvaluate);
                      }
                      num = Mathf.Lerp(this.limitMin, this.limitMax, num);
              this.animator.SetFloat(this.paramID, num);
                  }
              }
              LookAtRotator (huge)

              Code:
              public class LookAtRotator : MonoBehaviour
              {
              public enum TYPE
                  {
                      NO,
                      TARGET,
                      AWAY,
                      FORWARD,
                      DIRECTION,
                      DIRECTION_UNLIMITED,
                      HOLD
                  }
              
                  [Serializable]
              private class RotateBone
                  {
              public Transform bone;
              
              public float maxLeft = 45f;
              
              public float maxRight = 45f;
              
              protected Quaternion baseRot;
              
              protected Vector3 euler;
              
              protected Vector3 prevEuler;
              
              public Vector3 Euler
                      {
              get
                          {
              return this.euler;
                          }
              set
                          {
              this.euler = value;
                          }
                      }
              
              public Vector3 PrevEuler
                      {
              get
                          {
              return this.prevEuler;
                          }
              set
                          {
              this.prevEuler = value;
                          }
                      }
              
              public virtual void Init()
                      {
              this.baseRot = this.bone.localRotation;
              this.euler = Vector3.zero;
                      }
              
              public virtual void Change()
                      {
              this.prevEuler = this.euler;
                      }
              
              public virtual void Rotate(Quaternion rot)
                      {
              this.bone.localRotation = this.baseRot * rot;
                      }
              
              public virtual void ResetRotate()
                      {
              this.bone.localRotation = this.baseRot;
                      }
              
              public virtual void LerpAngle(Vector3 rel, float noRate)
                      {
              this.euler.x = Mathf.LerpAngle(this.prevEuler.x, rel.x, noRate);
              this.euler.y = Mathf.LerpAngle(this.prevEuler.y, rel.y, noRate);
              this.euler.z = Mathf.LerpAngle(this.prevEuler.z, rel.z, noRate);
                      }
              
              public virtual void Interpolation(Vector3 rel, float speed, float min, float max)
                      {
              this.euler.y = Tween.Spring(this.euler.y, rel.y, speed, Time.deltaTime, min, max);
              this.euler.x = Tween.Spring(this.euler.x, rel.x, speed, Time.deltaTime, min, max);
              this.euler.z = Tween.Spring(this.euler.z, rel.z, speed, Time.deltaTime, min, max);
                      }
                  }
              
                  [SerializeField]
              protected Transform baseBone;
              
                  [SerializeField]
              protected Transform target;
              
                  [SerializeField]
              protected Vector3 targetPos;
              
                  [SerializeField]
              protected LookAtRotator.RotateBone[] rotateBones;
              
              protected Vector3? prevTarget;
              
                  [Range(0f, 90f), SerializeField]
              protected float maxUp = 45f;
              
                  [Range(0f, 90f), SerializeField]
              protected float maxDown = 45f;
              
                  [Range(0f, 2f), SerializeField]
              protected float turnRate = 1f;
              
                  [Range(-45f, 45f), SerializeField]
              protected float offsetPitch;
              
                  [SerializeField]
              protected float turnPower = 3f;
              
                  [SerializeField]
              protected float turnMinSpeed = 1f;
              
                  [SerializeField]
              protected float turnMaxSpeed;
              
                  [SerializeField]
              protected float ignoreYaw = 120f;
              
                  [SerializeField]
              protected float awayIgnoreYaw = 45f;
              
              protected Quaternion baseLocalRot;
              
                  [SerializeField]
              protected LookAtRotator.TYPE calcType;
              
              protected float noRate;
              
              public LookAtRotator.TYPE CalcType
                  {
              get
                      {
              return this.calcType;
                      }
                  }
              
              public virtual void Init()
                  {
              this.baseLocalRot = this.baseBone.transform.localRotation;
              if (this.rotateBones != null && this.rotateBones.Length > 0)
                      {
              for (int i = 0; i < this.rotateBones.Length; i++)
                          {
              this.rotateBones[i].Init();
                          }
                      }
                  }
              
              public virtual void Calc()
                  {
              if (this.calcType == LookAtRotator.TYPE.NO)
                      {
              return;
                      }
                      Vector3 localEulerAngles = this.baseBone.transform.localEulerAngles;
                      localEulerAngles.x = Mathf.DeltaAngle(0f, localEulerAngles.x);
                      localEulerAngles.y = Mathf.DeltaAngle(0f, localEulerAngles.y);
                      localEulerAngles.z = Mathf.DeltaAngle(0f, localEulerAngles.z);
                      LookAtRotator.RotateBone[] array = this.rotateBones;
              for (int i = 0; i < array.Length; i++)
                      {
                          LookAtRotator.RotateBone rotateBone = array[i];
                          rotateBone.ResetRotate();
                      }
              this.baseBone.transform.localRotation = this.baseLocalRot;
              if (this.target && (this.calcType == LookAtRotator.TYPE.TARGET || this.calcType == LookAtRotator.TYPE.AWAY))
                      {
              this.targetPos = this.target.transform.position;
                      }
                      Vector3 vector = this.baseBone.InverseTransformPoint(this.targetPos);
                      Vector3 vector2 = Vector3.zero;
                      LookAtRotator.RotateBone[] array2 = this.rotateBones;
              for (int j = 0; j < array2.Length; j++)
                      {
                          LookAtRotator.RotateBone rotateBone2 = array2[j];
              if (this.calcType == LookAtRotator.TYPE.NO)
                          {
                              vector2 = localEulerAngles;
                          }
              else if (this.calcType == LookAtRotator.TYPE.TARGET)
                          {
                              VectorUtility.Vector3_ToYawPitch(vector, out vector2.y, out vector2.x);
                              vector2.y = Mathf.DeltaAngle(0f, vector2.y);
                              vector2.x = Mathf.DeltaAngle(0f, vector2.x) + this.offsetPitch;
              if (this.prevTarget.HasValue && Mathf.Abs(vector2.y) >= this.ignoreYaw)
                              {
                                  VectorUtility.Vector3_ToYawPitch(this.prevTarget.Value, out vector2.y, out vector2.x);
                                  vector2.y = Mathf.DeltaAngle(0f, vector2.y);
                                  vector2.x = Mathf.DeltaAngle(0f, vector2.x) + this.offsetPitch;
                              }
              else
                              {
              this.prevTarget = new Vector3?(vector);
                              }
                              vector2 *= this.turnRate;
                              vector2.y = Mathf.Clamp(vector2.y, -rotateBone2.maxLeft, rotateBone2.maxRight);
                              vector2.x = Mathf.Clamp(vector2.x, -this.maxUp, this.maxDown);
                              vector2.z = 0f;
                          }
              else if (this.calcType == LookAtRotator.TYPE.FORWARD)
                          {
                              vector2.y = 0f;
                              vector2.x = this.offsetPitch;
                              vector2.y = Mathf.Clamp(vector2.y, -rotateBone2.maxLeft, rotateBone2.maxRight);
                              vector2.x = Mathf.Clamp(vector2.x, -this.maxUp, this.maxDown);
                              vector2.z = 0f;
                          }
              else if (this.calcType == LookAtRotator.TYPE.DIRECTION)
                          {
                              vector2.y = this.targetPos.y;
                              vector2.x = this.targetPos.x + this.offsetPitch;
                              vector2.y = Mathf.Clamp(vector2.y, -rotateBone2.maxLeft, rotateBone2.maxRight);
                              vector2.x = Mathf.Clamp(vector2.x, -this.maxUp, this.maxDown);
                              vector2.z = 0f;
                          }
              else if (this.calcType == LookAtRotator.TYPE.DIRECTION_UNLIMITED)
                          {
                              vector2.y = this.targetPos.y;
                              vector2.x = this.targetPos.x + this.offsetPitch;
                              vector2.z = 0f;
                          }
              else if (this.calcType == LookAtRotator.TYPE.AWAY)
                          {
                              Vector3 zero = Vector3.zero;
                              VectorUtility.Vector3_ToYawPitch(vector, out zero.y, out zero.x);
                              zero.y = Mathf.DeltaAngle(0f, zero.y);
                              zero.x = Mathf.DeltaAngle(0f, zero.x) + this.offsetPitch;
              if (this.prevTarget.HasValue && Mathf.Abs(zero.y) <= this.awayIgnoreYaw)
                              {
                                  VectorUtility.Vector3_ToYawPitch(this.prevTarget.Value, out zero.y, out zero.x);
                                  zero.y = Mathf.DeltaAngle(0f, zero.y);
                                  zero.x = Mathf.DeltaAngle(0f, zero.x) + this.offsetPitch;
                              }
              else
                              {
              this.prevTarget = new Vector3?(vector);
                              }
                              vector2.y = ((zero.y <= 0f) ? rotateBone2.maxRight : (-rotateBone2.maxLeft));
                              vector2.x = ((zero.x <= 0f) ? this.maxDown : (-this.maxUp));
                              vector2.z = 0f;
                          }
              if (this.calcType == LookAtRotator.TYPE.HOLD)
                          {
                              rotateBone2.PrevEuler = rotateBone2.Euler;
                              Quaternion rhs = Quaternion.Euler(rotateBone2.Euler);
                              Quaternion rot = this.baseLocalRot * rhs;
                              rotateBone2.Rotate(rot);
                          }
              else
                          {
                              rotateBone2.Interpolation(vector2, this.turnPower, this.turnMinSpeed, this.turnMaxSpeed);
                              rotateBone2.PrevEuler = rotateBone2.Euler;
                              Quaternion quaternion = Quaternion.Euler(rotateBone2.Euler);
                              Quaternion quaternion2 = this.baseLocalRot * quaternion;
                              rotateBone2.Rotate(quaternion);
                          }
                      }
                  }
              
              public virtual void Change(LookAtRotator.TYPE type, Transform tgt, bool force)
                  {
              this.calcType = type;
              this.target = tgt;
              if (tgt)
                      {
              this.targetPos = tgt.position;
                      }
              this.noRate = ((!force) ? 0f : 1f);
                      LookAtRotator.RotateBone[] array = this.rotateBones;
              for (int i = 0; i < array.Length; i++)
                      {
                          LookAtRotator.RotateBone rotateBone = array[i];
                          rotateBone.Change();
                      }
                  }
              
              public virtual void Change(LookAtRotator.TYPE type, Vector3 tgt, bool force)
                  {
              this.calcType = type;
              this.targetPos = tgt;
              this.target = null;
              this.noRate = ((!force) ? 0f : 1f);
                      LookAtRotator.RotateBone[] array = this.rotateBones;
              for (int i = 0; i < array.Length; i++)
                      {
                          LookAtRotator.RotateBone rotateBone = array[i];
                          rotateBone.Change();
                      }
                  }
              
              public virtual void Start()
                  {
              this.Init();
                  }
              
              public virtual void LateUpdate()
                  {
              this.Calc();
                  }
              }
              My blog, you can find my mods there too.

              Comment


              • #26
                this yt page post video about playhome.. what kind of MOD he is showing?
                http://www.youtube.com/channel/UCnoV...WOX9V6w/videos

                Comment


                • Zohan9222
                  Zohan9222 commented
                  Editing a comment
                  yeahhh someone know ????????

                • Wweerr
                  Wweerr commented
                  Editing a comment
                  seems someone is really advanced in this game's modding

                • numenume1
                  numenume1 commented
                  Editing a comment
                  Zohan9222 can you share your girl from your profile pic...SHE LOOKS AWSOME.

              • #27
                I make an uncensored patch for female,but the game data is huge so I just upload the key files.
                https://mega.nz/#!gstiEKZT!Kd4JPTTc1...s-m65Tb63ICENA

                Comment


                • Taden
                  Taden commented
                  Editing a comment
                  I'm also not finding where to put the meshes, I'd love to know if this can be made to work

                • MrMakarov
                  MrMakarov commented
                  Editing a comment
                  Thank you for doing this, but I do not understand how to do the replacing... it would be nice, if you can help!

                • otropas
                  otropas commented
                  Editing a comment
                  How do you install the MQO files, I got the DDS files replaced but can't for the life of me figure out the MQO files, its been 2 hours and I just can't do it...
                  Please, some one help? I can't find a guide on here on how to do it.

              • #28
                ssseeesss
                Since the uncensor was released as a workfile and without proper instructions I have moved it into the modding discussion. Please post how to apply your workfiles for the less enlightened. Thank you.

                Comment


                • #29
                  Sb3UGS v1.7.8 allows to work a little more freely on the male naked character.

                  Click image for larger version  Name:	VirtualAnimators.jpg Views:	1 Size:	296.7 KB ID:	5822817
                  The LineRenderer and TrailRenderer assets dont get invalid with the updated version and you can edit Attributes and Material assignments. Still the combined hierarchy with the three skeletons requires to work with some tricks in Sb3UGS.
                  • When you open p_cm_anim Animator you can see that the root of the hierarchy is MaleBody and not p_cm_anim. In such cases the Avatar is not correctly used by Sb3UGS. Make cm_body_mnpb to a virtual Animator, close p_cm_anim Animator and open cm_body_mnpb instead.
                  • In each of the four childs of MaleBody is a skeleton and a Transform chain with meshes. To work in one of these childs: move them to the top first! Then edit in them, e.g. make replacements of meshes, and after editing move them back to where they came from.

                  Example of a very simple male uncensor. This uncensor does not have the same colour as the body and it cant be coloured in the game, and of course it does not solve the telescoping problem. The example just demonstrates how to work in those hierarchies.
                  1. open the virtual Animator cm_body_mnpb as described above
                  2. select cm_body_mnpb Transform and move it up thrice! It should be the first child of MaleBody Transform then.
                  3. expand cm_body_mnpb until you see N_dan Transform. Select N_dan and "Create" a new child Transform.
                    Click image for larger version  Name:	SimpleMaleUncensor01.jpg Views:	1 Size:	185.0 KB ID:	5822818
                  4. I renamed it to cm_U_unce and copied the matrix of a sibling to it.
                  5. Then I replaced with an older uncensor and used the cm_U_unce as Destination Transform.
                    Click image for larger version  Name:	SimpleMaleUncensor02.jpg Views:	1 Size:	251.7 KB ID:	5822819
                  6. Then set the material to the body's.
                    Click image for larger version  Name:	SimpleMaleUncensor03.jpg Views:	1 Size:	301.6 KB ID:	5822820
                  7. To hide the original meshes with mosaic I disabled "isActive" in the sibling Transforms.
                  8. Dont forget to move cm_body_mnpb back!



                  Spoiler
                  Click image for larger version  Name:	20170919181933197.png Views:	1 Size:	36.0 KB ID:	5822821
                  Last edited by enimaroah; 10-29-2017, 12:48 PM. Reason: Location of virtual Animator needed correction

                  Comment


                  • AlterioEgocentrio
                    AlterioEgocentrio commented
                    Editing a comment
                    i tryed to open that hierarchy for male uncensor but its a little bit different, maybe its because i opened official and you trial version

                  • Moborius
                    Moborius commented
                    Editing a comment
                    Thx for the instructions. Although I have some trouble to find an 'older uncensor'. Because of my inexperience I can't get the uncensor out of the resources.asset from honeselect. Is there a file on Hongfire we can use to practise your tutorial (above)?
                    Last edited by Moborius; 10-25-2017, 07:10 AM.

                • #30
                  New Top Clothes for the Trial - Part I
                  An extra file for the list entry and geometry:
                  1. copy
                    Code:
                    PlayHomeTrial_Data\StreamingAssets\customtexture\cf_t_mole_hs00 wear\cf_panst_trial
                    to
                    Code:
                    PlayHomeTrial_Data\StreamingAssets\wear
                    and rename it to cf_top_demo
                  2. make the CAB-String unique
                  3. delete all textures in the file
                  This base file could be used for other clothes as well, but you will always have to make the CAB-String unique.
                  Transport an original costume into the new file:
                  • open cf_top_trial in the same folder of the your new file
                  • open TextAsset cf_top_Trial_list from "MonoB. Other" tab and choose one line of a costume
                    Note the values of the Prefab and Normal columns!
                  • From "MonoB. & Other" tab select cf_top_Trial_list and the MonoBehaviour ending with _Nml from the Normal column, e.g. p_cf_body_top_38_Nml. Then "Mark for Copying"
                  • select the Animator from the Prefab column, e.g. p_cf_top_38_00. Then "Mark for Copying"
                  • open your new file cf_top_demo or switch to it, then "Paste All Marked". You will get two warnings in the Log window. We will correct this later.
                  • rename the cf_top_Trial_list to cf_top_demo_list. (filename + "_list")
                  • rename the Animator p_cf_top_38_00 to p_cf_body_top_22_00. The name must be unique to prevent a collision in the thumbnail file.
                  • open cf_top_demo_list
                  • delete all lines except the one of the chosen costume
                  • adapt the name of the Prefab, make the costum ID unique
                  New thumbnail entry:
                  In
                  Code:
                  PlayHomeTrial_Data\StreamingAssets\thumnbnail\thumbnail_weartop
                  add an image with the name of the Animator, e.g. p_cf_body_top_22_00. The image should be 256x256 format=RGB24, ColorSpace=1, Filter=1, Aniso=1 the rest unchecked / 0

                  Now your costume is selectable in the trial. But because of the two warnings it has no normal correction for small chested girls. This tutorial will have a second part with modifications to the costume and the skipped normal correction.
                  Last edited by enimaroah; 09-22-2017, 04:12 AM. Reason: Workaround for bug in Sb3UGS

                  Comment


                  • hyperionx
                    hyperionx commented
                    Editing a comment
                    there is a way to include a miniature in the mod? so it integrates itself as a new entry by adding an external file e.g thumnbs_bodytattoo_f_xxx?
                    i tested the lwlin solution (thumnbnail_R folder).......... but not work!
                    Last edited by hyperionx; 10-16-2017, 08:22 AM.
                Working...
                X