This was intended for the contest at the other site, but because of their missmanagement of the contest it didn't get a chance to be submitted. So I am posting it here to help illustrate what can be done.
Nice work Charles :) I like the camera work and lighting, Will you be doing a video on how you make your movies? Because that's something I'd be very interested in watching.
Nice work Charles :) I like the camera work and lighting, Will you be doing a video on how you make your movies? Because that's something I'd be very interested in watching.
Since you asked, ABSOLUTELY! What you want ot know?
I would assume you are experienced with Unity and Daz?
The camera work is not cinamachine, I did explore that but abondoned it quickly. Instead it's based on either DoTween pathing and LookAt, or just fixing the camera to the charater root at at an angle, or just setting the camera in a static position.
Static, the shot of her running down the trail and the bridge are both static. She is controlled with PlayMaker character 3rd person controller. I don't really care much for PlayMaker but for this project it just made things easier. When making her run for these scenes I controlled her while looking at the editor view with a simple script to auto follow in editor. This also allowed me to create waypoints to see there which wouldn't appear in the video to know where the hell I was going..lol...because it was really easy to get lost especially in the night scenes.
Of course this was shot using the HDRP.
The camera to make it feel more retro with lush depth and the ability to capture video I used Evereal.VideoCapture.
The character animation is based on blending Daz poses+Daz Animation sequences with Unity Asset FemaleMovementAnimset.
However when exporting to unity via bridge, I included a lot of blendshapes, for face, body and hair. Custom script was written to randomize more Dotweens for these blendshapes. Eye movement were also created via scripted blendspaes that utilized a box offset in front of her face on the head, and used dot vector references to figure out if her head was to the left/right up/down of the center and made eyes + hair interact according to the dot reference.
All sound effects were done post in Adobe Premiere.
Here is a snippet of code that help see the process. I was on an extremely tight deadline so this is really scrappy code.
void Update()
{
if (StopAll == true) return;
if (actionHappening == true) return;
Vector3 toTarget = LookBox.transform.position - mainCharObj.transform.position;
float dot = Vector3.Dot(toTarget, mainCharObj.transform.right);
float dot2 = Vector3.Dot(toTarget, mainCharObj.transform.up); // 1.45 is about center, 1.55 high, 1.4 low
//Debug.Log(dot);
//Debug.Log(dot2);
if (Random.Range(0, 3) == 0) // zero all
{
if (GetBSValue("1_acting_speaking_look_up") != 0f)
{
DOTween.To(myBlends["1_acting_speaking_look_up"].call, GetBSValue("1_acting_speaking_look_up"), 0f, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_up");
}
if (GetBSValue("1_acting_speaking_look_down") != 0f)
{
DOTween.To(myBlends["1_acting_speaking_look_down"].call, GetBSValue("1_acting_speaking_look_down"), 0f, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_down");
}
if (GetBSValue("1_acting_speaking_look_side_right") != 0f)
{
DOTween.To(myBlends["1_acting_speaking_look_side_right"].call, GetBSValue("1_acting_speaking_look_side_right"), 0f, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_right");
}
if (GetBSValue("1_acting_speaking_look_side_left") != 0f)
{
DOTween.To(myBlends["1_acting_speaking_look_side_left"].call, GetBSValue("1_acting_speaking_look_side_left"), 0f, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_left");
}
}
else
{
int r = Random.Range(0, 5);
if (r == 0) // side to side // left
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
DOTween.To(myBlends["1_acting_speaking_look_side_left"].call, GetBSValue("1_acting_speaking_look_side_left"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_left");
}
else if(r == 1) // right
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
DOTween.To(myBlends["1_acting_speaking_look_side_right"].call, GetBSValue("1_acting_speaking_look_side_right"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_right");
}
else // dot
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
Debug.Log("DOT2=" + dot2);
r = Random.Range(0, 5);
if (r == 0) // up and down // up
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
DOTween.To(myBlends["1_acting_speaking_look_up"].call, GetBSValue("1_acting_speaking_look_up"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_up");
}
else if (r == 1) // up and down // down
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
DOTween.To(myBlends["1_acting_speaking_look_down"].call, GetBSValue("1_acting_speaking_look_down"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_down");
}
else // dot2
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
lookingDirection = 1;
// Target is to the right (head rotates clockwise when viewed from above).
}
else if (dot < -dot_LR_sensor)
{
//Debug.Log("Look Left");
Nice work Charles :) I like the camera work and lighting, Will you be doing a video on how you make your movies? Because that's something I'd be very interested in watching.
Since you asked, ABSOLUTELY! What you want ot know?
I think you've explained a lot of the process when it comes to making your movie, but could you touch on the lighting? Like do you use HDRI, do you use a direct light or spot lights and also do you use any post processing.
I would assume you are experienced with Unity and Daz?
Yeah. I'm also playing around with a demo version of Chacter creator, but it's so expensive.
Comments
Nice work Charles :) I like the camera work and lighting, Will you be doing a video on how you make your movies? Because that's something I'd be very interested in watching.
Impressive, thanks for sharing!
Since you asked, ABSOLUTELY! What you want ot know?
I would assume you are experienced with Unity and Daz?
The camera work is not cinamachine, I did explore that but abondoned it quickly. Instead it's based on either DoTween pathing and LookAt, or just fixing the camera to the charater root at at an angle, or just setting the camera in a static position.
Static, the shot of her running down the trail and the bridge are both static. She is controlled with PlayMaker character 3rd person controller. I don't really care much for PlayMaker but for this project it just made things easier. When making her run for these scenes I controlled her while looking at the editor view with a simple script to auto follow in editor. This also allowed me to create waypoints to see there which wouldn't appear in the video to know where the hell I was going..lol...because it was really easy to get lost especially in the night scenes.
Of course this was shot using the HDRP.
The camera to make it feel more retro with lush depth and the ability to capture video I used Evereal.VideoCapture.
The character animation is based on blending Daz poses+Daz Animation sequences with Unity Asset FemaleMovementAnimset.
However when exporting to unity via bridge, I included a lot of blendshapes, for face, body and hair. Custom script was written to randomize more Dotweens for these blendshapes. Eye movement were also created via scripted blendspaes that utilized a box offset in front of her face on the head, and used dot vector references to figure out if her head was to the left/right up/down of the center and made eyes + hair interact according to the dot reference.
All sound effects were done post in Adobe Premiere.
Here is a snippet of code that help see the process. I was on an extremely tight deadline so this is really scrappy code.
void Update()
{
if (StopAll == true) return;
if (actionHappening == true) return;
Vector3 toTarget = LookBox.transform.position - mainCharObj.transform.position;
float dot = Vector3.Dot(toTarget, mainCharObj.transform.right);
float dot2 = Vector3.Dot(toTarget, mainCharObj.transform.up); // 1.45 is about center, 1.55 high, 1.4 low
//Debug.Log(dot);
//Debug.Log(dot2);
// [BLINK]
blinkTimer = blinkTimer - Time.deltaTime;
if(blinkTimer < 0f)
{
blinkTimer = Random.Range(blinkMin, blinkMax);
DOTween.Kill("facs_bs_eyesquintleft_div2");
DOTween.Kill("facs_bs_eyesquintright_div2");
float blinkspeed = Random.Range(.1f, .3f);
DOTween.To(myBlends["facs_bs_eyesquintleft_div2"].call, GetBSValue("facs_bs_eyesquintleft_div2"), 200f, blinkspeed).SetEase(Ease.Flash).OnComplete(() => BlinkEnd("facs_bs_eyesquintleft_div2", blinkspeed)).SetId("facs_bs_eyesquintleft_div2");
DOTween.To(myBlends["facs_bs_eyesquintright_div2"].call, GetBSValue("facs_bs_eyesquintright_div2"), 200f, blinkspeed).SetEase(Ease.Flash).OnComplete(() => BlinkEnd("facs_bs_eyesquintright_div2", blinkspeed)).SetId("facs_bs_eyesquintright_div2");
}
/// [LOOKING]
//1_acting_speaking_look_up
//1_acting_speaking_look_down
//1_acting_speaking_look_side_right
//1_acting_speaking_look_side_left
lookAboutTimer = lookAboutTimer - Time.deltaTime;
float rt = Random.Range(.25f, 1f);
if (_rt > 0f) rt = _rt;
if (lookAboutTimer < 0f)
{
lookAboutTimer = Random.Range(lookAboutMin, lookAboutMax);
DOTween.Kill("1_acting_speaking_look_up");
DOTween.Kill("1_acting_speaking_look_down");
DOTween.Kill("1_acting_speaking_look_side_right");
DOTween.Kill("1_acting_speaking_look_side_left");
if (Random.Range(0, 3) == 0) // zero all
{
if (GetBSValue("1_acting_speaking_look_up") != 0f)
{
DOTween.To(myBlends["1_acting_speaking_look_up"].call, GetBSValue("1_acting_speaking_look_up"), 0f, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_up");
}
if (GetBSValue("1_acting_speaking_look_down") != 0f)
{
DOTween.To(myBlends["1_acting_speaking_look_down"].call, GetBSValue("1_acting_speaking_look_down"), 0f, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_down");
}
if (GetBSValue("1_acting_speaking_look_side_right") != 0f)
{
DOTween.To(myBlends["1_acting_speaking_look_side_right"].call, GetBSValue("1_acting_speaking_look_side_right"), 0f, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_right");
}
if (GetBSValue("1_acting_speaking_look_side_left") != 0f)
{
DOTween.To(myBlends["1_acting_speaking_look_side_left"].call, GetBSValue("1_acting_speaking_look_side_left"), 0f, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_left");
}
}
else
{
int r = Random.Range(0, 5);
if (r == 0) // side to side // left
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
DOTween.To(myBlends["1_acting_speaking_look_side_left"].call, GetBSValue("1_acting_speaking_look_side_left"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_left");
}
else if(r == 1) // right
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
DOTween.To(myBlends["1_acting_speaking_look_side_right"].call, GetBSValue("1_acting_speaking_look_side_right"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_right");
}
else // dot
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
if (dot > .1f)
{
DOTween.To(myBlends["1_acting_speaking_look_side_right"].call, GetBSValue("1_acting_speaking_look_side_right"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_right");
}
else
{
DOTween.To(myBlends["1_acting_speaking_look_side_left"].call, GetBSValue("1_acting_speaking_look_side_left"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_side_left");
}
}
Debug.Log("DOT2=" + dot2);
r = Random.Range(0, 5);
if (r == 0) // up and down // up
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
DOTween.To(myBlends["1_acting_speaking_look_up"].call, GetBSValue("1_acting_speaking_look_up"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_up");
}
else if (r == 1) // up and down // down
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
DOTween.To(myBlends["1_acting_speaking_look_down"].call, GetBSValue("1_acting_speaking_look_down"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_down");
}
else // dot2
{
float am = Random.Range(40, 120);
if (am > 100) am = 95;
if (dot2 > dot)
{
DOTween.To(myBlends["1_acting_speaking_look_up"].call, GetBSValue("1_acting_speaking_look_up"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_up");
}
else
{
DOTween.To(myBlends["1_acting_speaking_look_down"].call, GetBSValue("1_acting_speaking_look_down"), am, rt).SetEase(Ease.Flash).SetId("1_acting_speaking_look_down");
}
}
}
}
if (Mathf.Approximately(dot, 0f))
{
// Target is straight ahead.
//Debug.Log("Look Center");
if (lookingDirection == 1)
{
KickHairOverride("wind-l", Random.Range(30f, 50f));
KickHairOverride("blow-dial01detail", Random.Range(30f, 50f));
}
else if (lookingDirection == -1)
{
KickHairOverride("wind-r", Random.Range(30f, 50f));
KickHairOverride("blow-dial02detail", Random.Range(30f, 50f));
}
lookingDirection = 0;
}
else if (dot > dot_LR_sensor)
{
//Debug.Log("Look Right");
if (lookingDirection == 0)
{
KickHairOverride("wind-r", Random.Range(30f, 50f));
KickHairOverride("blow-dial02detail", Random.Range(30f, 50f));
}
else if (lookingDirection == -1)
{
KickHairOverride("wind-r", Random.Range(50f, 100f));
KickHairOverride("blow-dial02detail", Random.Range(50f, 100f));
}
lookingDirection = 1;
// Target is to the right (head rotates clockwise when viewed from above).
}
else if (dot < -dot_LR_sensor)
{
//Debug.Log("Look Left");
if (lookingDirection == 0)
{
KickHairOverride("wind-l", Random.Range(30f, 50f));
KickHairOverride("blow-dial01detail", Random.Range(30f, 50f));
}
else if (lookingDirection == 1)
{
KickHairOverride("wind-l", Random.Range(50f, 100f));
KickHairOverride("blow-dial01detail", Random.Range(50f, 100f));
}
lookingDirection = -1;
// Target is to the left (lead rotates counter-clockwise when viewed from above).
}
}