امتیاز موضوع:
  • 6 رأی - میانگین امتیازات: 4.67
  • 1
  • 2
  • 3
  • 4
  • 5

[-]
کلمات کلیدی
برنامه نویسی و راهکارهایی در یونیتی

برنامه نویسی و راهکارهایی در یونیتی
#21
با هر دوش کار کن. هر جا این یکی کار نکرد یه اسکریپت جاوا بنویس و هرجا js کار نکرد cs بنویس. واسه یک گیم ابجکت میشه هم اسکریپت js داد هم cs همزمان. smiley
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#22
مباحث ساده هوش مصنوعی
http://promakers.ir/showthread.php?tid=8810
http://promakers.ir/showthread.php?tid=1...#pid109686

تشکرها کم بود ولی عیبی نداره . در درس بعدی Lerp رو یاد می دم و بعدش احتمال داره روی Slerp بحث کنم. با توجه به اینکه به سایت های زیادی سر می زنم سعی می کنم مفهومی رو که خودم تست کردم و درک کردم خلاصه و مفید یاد بدم اونطوری که کاربردی باشه.
تابع Lerp
یه اسکریپت js با کد زیر ایجاد کنید :
کد php:
//lerp.js
using UnityEngine;
using System
public class LightLerpMonoBehaviour
{
private 
Vector3 newPosition;
void Awake()
{
newPosition transform.position;
}
void Update()
{
PositionChanging();
}

PositionChanging()
{
Vector3 positionA = new Vector3(-5,3,0);
Vector3 positionB = new Vector3(5,3,0);

if(
Input.GetKeyDown(KeyCode.Q))
newPosition positionA;

if(
Input.GetKeyDown(KeyCode.E))
newPosition positionB;

transform.posision=newPosision;
}

اگه کد اشتباه داشت برطرف کنید چون همشون رو از روی فیلم سایت اصلی یونیتی تایپ کردم.
یه نور نقطه ای بذارید روی صحنه(point light) . شدت نور رو کمی زیاد کنید(خصوصیت Identsity) تا روی plane به چشم بیاد.
اسکریپت فوق رو بدید به نور(بکشید روش رها کنید).
اجرا کنید .
طبق اسکریپت اگه Q بزنیم نور به موقع positionA میره و اگه E بزنیم به نقطه ی positionB .
شما اینو اجرا کنید می تونید ببینید چی می گم.( نور جابجا میشه )

اما اصلا زیبایی خاصی نداره و فقط عمل پرش رو انجام میده و پیوسته نیست و گسسته هست.

برای اینکه نور با یک سرعت تعریف شده از نقطه ی A به نقطه ی B بره از تابع Lerp استفاده می کنیم.

مثال شکل کلی استفاده از Lerp :
کد php:
transform.position Vector3.Lerp(transform.positionnewPositionsmooth Time.deltaTime); 

تابع Lerp سه تا پارامتر می گیره :

From : از
To: به
t : من بهش می گم time و شما هم بگید time.
(با این که t مخفف چی هست و چی نیست یا اصلا غلط هست یا درست هم کاری نداشته باشید بذارید ما درس خودمون رو بدیم و اگه زیبا نبود بیخیالش بشید. اینم بگم خودم مقالات سایت رفرنس و سایت های ایرانی و خارجی زیادی رو مطالعه می کنم ولی مهم نیست همون time اسم گذاری کنید.)

به جای t مقدار smooth * Time.deltaTime رو بدید و به جای From و To هم متغیری از نوع بردار سه بعدی (در درس ما A و B) رو بدید.

smooth هم در بخش public(بالای برنامه) تعریف می کنید از نوع float(اعشاری).

و بعد از نسنب دادن اسکریپت به نور نقطه ای، خصوصیت smooth رو با مقدار 1 عدد بدید(اگه بیشترش کنید روان بودن و سرعت حرکت بیشتر میشه. این smooth داره در Time.deltaTime ضرب میشه و طبیعی هست دیگه هرچی بیشتر باشه سرعت زمانی حرکت نور بالا میره)

وقتی پروژه رو اجرا کنید با فشردن کلید Q و E نور به آرومی بین نقاط سه بعدی A و B تغییر موقعیت میده.

تا شما یه چایی بخورید من یاد میدم که Lerp چه کاربردهای دیگه ای داره و کجاها میشه ازش استفاده کردteeth

سه مثال کاربردی از روش استفاده از تابع Lerp :

معمولا گیم ابجکت های مختلفی هستند که از تابع Lerp استفاده می کنند.

سه حالت رو مثال می زنم:

حالت اول :
کد:
transform.position = Vector3.Lerp(transform.position, newPosition, smooth * Time.deltaTime);
کد بالا رو شرح دادم.پس بیخیالش.

حالت دوم :
کد:
light.intensity = Mathf.Lerp(light.intensity, newIntensity, smooth * Time.deltaTime);
این کد باعث میشه شدت نور از حالت فعلی به حالت newIntensity بره و طبق دستوراتی که اسکریپتی که بهتون میدم میگم چیکار کنید.

حالت سوم :
کد:
light.color = Color.Lerp(light.color, newColour, smooth * Time.deltaTime);
این کد برای تغییر رنگ نور از رنگ فعلی به رنگ جدید که در متغیر newColour تعریف شده بکار می ره. تیو اسکریپت که در ادامه میارم یادتون میدم ببینید چقدر زیباست و یاد گرفتنش از روی راهنمایی من چه قدر خوبهsmiley

الان بر می گردم و یه اسکریپت کامل براتون میذارم تا تست کنید.

خوب برگشتم:

این کلیپ بی کیفیت که من ساختم رو ببینید تا قدرت Lerp رو درک کنید :
http://s5.picofile.com/file/8153633500/c...1.zip.html

حالا روش ساخت :

یه پروژه 3d ایجاد کنید با این اجزا : main Camera ، plane و Point Light

اسکریپت js زیر رو بدید به نور نقطه ای (point Light):
کد php:
#pragma strict

public var smooth float;

private var 
newPosition Vector3;
private var 
newIntensity float;
private var 
newColour Color;


function 
Awake ()
{
    
newPosition transform.position;
    
newIntensity light.intensity;
    
newColour light.color;
}


function 
Update ()
{
    
PositionChanging();
    
IntensityChanging();
    
ColourChanging();
}


function 
PositionChanging ()
{
    var 
positionA Vector3 = new Vector3(-530);
    var 
positionB Vector3 = new Vector3(530);
    
    if(
Input.GetKeyDown(KeyCode.Q))
        
newPosition positionA;
    if(
Input.GetKeyDown(KeyCode.E))
        
newPosition positionB;
    
    
transform.position Vector3.Lerp(transform.positionnewPositionsmooth Time.deltaTime);
}


function 
IntensityChanging ()
{
    var 
intensityA float 0.5f;
    var 
intensityB float 5f;
    
    if(
Input.GetKeyDown(KeyCode.A))
        
newIntensity intensityA;
    if(
Input.GetKeyDown(KeyCode.D))
        
newIntensity intensityB;
    
    
light.intensity Mathf.Lerp(light.intensitynewIntensitysmooth Time.deltaTime);
}


function 
ColourChanging ()
{
    var 
colourA Color Color.red;
    var 
colourB Color Color.green;
    
    if(
Input.GetKeyDown(KeyCode.Z))
        
newColour colourA;
    if(
Input.GetKeyDown(KeyCode.C))
        
newColour colourB;
    
    
light.color Color.Lerp(light.colornewColoursmooth Time.deltaTime);

بعد از افزودن اسکریپت فوق به نور نقطه ای، نور رو انتخاب کنید و در پنجره ی خصوصیات یا inspector پارامتر Smooth رو بدید 1 یا 2 (یه عدد غیر صفر معمولا از 1 به بالا بدید که قبلا توضیحش دادم)

اجرا کنید .
با کلید های زیر بازی کنید:
Q و E
A و D
Z و C
--
خروجی :
resim
می بینید چقدر زیباست ؟ دقیقا عین چشماتون smiley
همین الان تست کنید و ببینید چه قدر قشنگه کار با یونیتی.
کاربرد این کد در هوش مصنوعی هم هست و دستوری به اسم (Quaternion.Slerp(From,To,Time داریم که برای درکش فقط کافیه همین Lerp ای که بالا توضیح دادم رو تست کنید و بعدش Slerp همون پارامترها رو می گیره که یه جایی به دردتون میخوره توضیحات من. مطمئن باشید توضیحاتی که من میارم صرفا کپی پیست هر چیزی نیست. سعی می کنم بگردم و چیزای خوبی که تست می کنم و رفرنس رو خودم اول درک کنم بعدش تست کنم اگه جواب داد براتون میارم و توضیح میدم. پس فکر نکنید پرومیکرز نسبت به سایت های دیگه چیزی کم داره. اگه چیز زیادتری نداشته باشه کمتر از سایت های دیگه نیست و قول میدم در آینده بچه های پرومیکرز خیلی پیشرفت کنند و آموزش های بهتری بسازم براتون.
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#23
تعریف آرایه ای از گیم ابجکت :
اسکریپت خود را به زبان js ایجاد در بخش تعریف متغیرهای سراسری (قبل از تابع Start) این را بنویسید:
کد:
var اسم دلخواه مجاز: Transform[];
مثال:
کد php:
var waypoints Transform[]; 

اسکریپت رو بندازید روی یه گیم ابجکت دلخواه.

گیم ابجکت رو انتخاب و به زیر شاخه ی اسکریپت در کادر خصوصیات(inspector) نگاه کنید و پارامتر size رو بیابید.

تغییرش بدید تا طول آرایه تغییر کنه.(مثال: اگه size رو دید 3 ، سه تا پارامتر Element0 و Element1 و Element2 ایجاد میشه.)

نوع رو چون Transform گذاشته بودیم می تونیم گیم ابجکت های دلخواه رو بکشیم بندازیم توی هریک از این سه سلول آرایه.

یک کاربرد : ساخت نقاط روی یک مسیر و استفاده برای مسیر یابی در بازی های مختلف(ورزشی،مسابقه ای،استراتژی و الی آخر...)

در بخش AI in Unity انجمن (زیر شاخه ی بخش مقالات اموزشی Unity) ساخت یک موجود هوشمند ساده رو با همین روش و یه دو تا کد کوچولو یادتون میدم. خودتون مراجعه کنید بعدا.wink
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#24
ساخت یک موجود هوشند با استفاده از waiypoints:
resim
در بخش هوش مصنوعی درسشو دادم.به این لینک مراجعه بفرمایید:
http://promakers.ir/showthread.php?tid=8...#pid109825
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#25
رندر به صورت wireFrame (سیمی) در یونیتی:
می خوام مثال قبل رو به صورت وایرفریم رندر بگیرم.
یک اسکریپت js ایجاد کنید و کدزیر رو توش ذخیره کنید و سپس به دوربین بدید:
کد php:
// Attach this script to a camera, this will make it render in wireframe
    
function OnPreRender() {
        
GL.wireframe true;
    }
    function 
OnPostRender() {
        
GL.wireframe false;
    } 
بازی رو اجرا کنید و از تماشا لذت ببرید:
resim

اون کره های زرد رو که می بینید فکر نکنید سیمی نیستن. بلکه چون فاصلشون از دوربین دور هست به چشم نمیان و خطای دید هست. اگه دوربین رو نزدیک کنید خوب میشه دید سیمی هستن.
نکته:این روش برای رندر کل ابجکت ها بود.
اگه فقط ابجکت های دلخواه ر بخواید سیمی رندر کنید یه سورس سیشارپی اینجا گذاشتم:
http://promakers.ir/showthread.php?tid=10210
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#26
چطور سیشارپ و جاوااسکریپت رو یادبگیریم ؟
چون بچه های زیادی مشکل داشتن تصمیم گرفتم کمی توضیح بدم :
واسه یادگیری سیشارپ باید CPP بلد باشید. ساختار سیشارپ همونه فقط یه سری چیزا اضافه میشه،که اونم خلاصه یاد میدم.
واسه یادگیری js هم کمی پاسکال بلد باشید و همون c کافیه.
یه مقایسه سطحی میندازم روی دستورات سی پلاس پلاس و سیشاپ و جاوااسکریپت یا همون js (دقت کنید js رو با JAVA اشتباه نگیرید چون جاوا یه زبون جداست که js زیرمجموعه ی JAVA میشه و ساختار JAVA رو بعدا یاد می دم اگه نیازی بود)

* در CPP یا C وقتی بخوایم یه فایل کتابخونه ای رو ضمیمه کنیم از دستور include استفاده می کنیم که ابتدای برنامه می یاریمش.
مثال :
کد:
روش اول:
#include <iostream.h>
روش دیگر :
#include "stdio.h"
فرق دو روش هم اینه که توی یکیش ابتدا مسیر جاری رو واسه یافتن می گرده توی یکی دیگه توی پوشه ی include رو می گرده واسه یافتن فایل های هیدر یا سرآیند با پسوند h ( یعنی header و فایل های کتابخونه ای که در سر برنامه می آن)


* در JS نیازی به بار یا ضمیمه کردن فایل های کتابخونه ای نیست و خود انجین وظیفه داره هر فایلی رو که نیاز بود ضمیمه کنه پس ساده تر هست از این جهت کدنویسی کمتر.


* در csharp از using استفاده می کنیم برای افزودن فضای نام یا namespace یا همون کلاس هایی که توی اسکریپت هاو برناممون می خوایم از اونا استفاده کنیم.
مثال:

کد:
using UnityEngine;
using System.Collections;
توی دستورات فوق فضای نام UnityEngine و System.Collections رو اوردم .
این دو تا رو میاریم چون بیشتر کدهایی که می نویسیم توابع یا دستوراتی هستن که توی کلاس UnityEngine و کلاس Collections (که خودش زیر مجموعه ی کلاس System میشه) تعریفشون وجود داره.

البته اگه این دستورات رو نیاریم دیگه هرکدی که می نویسیم دقیقا بدونیم توی کدوم کلاس تعریف شده .

به عنوان مثال وقتی از دستور Debug.Log برای چاپ یه پیام استفاده می کنیم باید اونو به صورت UnityEngine.Debug.Log بیاریم چون تابع Log در کلاس Debug تعریف شده و کلاس Debug هم در کلاس UnityEngine تعریف شده.

کلاس MonoBehaviour هم که در کلاس UnityEngine تعریف شده پس اگه فضای نام UnityEngine رو بالای برنامه ضممیه نکنیم باید به صورت UnityEngine.MonoBehaviour بیاد.

دستوراتی که در کلاس های دیگه تعریف شده رو هم باید شناخت و اسم کلاسشون رو بیاریم و بعدش علامت نقطه بزنیم و توابع زیرشاخه ی اونا رو که لیست میشه شناسایی کنیم که این کار چون شلوغ کاری هست از فضای نام استفاده می کنیم تا خلاصه بشه(یعنی همون آوردن اسم کلاس های مادر اونا که در بالا با using ضمیمه می کنیم)

مثال :
توی سیشارپ اگه بخوام اسکریپتی بسازم که پیام "Hello Promakers.ir " رو چاپ کنه کد اینطوری میشه:
کد php:
//using UnityEngine;
//using System.Collections;

public class NewBehaviourScript UnityEngine.MonoBehaviour {

    
// Use this for initialization
    
void Start () {
        
UnityEngine.Debug.Log("Hello promakers.ir");
    }
    
    
// Update is called once per frame
    
void Update () {
    
    }


می بینید فضای نام رو گذاشتم جزو توضیحات که بعد از دو تا علامت اسلش(//) آوردم(توضیحات چند خطی هم بین /**/ میاد که اینا همون ساختار سی پلاس پلس هست که اینجا نباید درس بدم توی بخش c بپرسید wink )

اگه در کد فوق دو خط زیر حزو توضیحات نباشه:
کد:
//using UnityEngine;
//using System.Collections;
دیگه اجباری به اوردنشون توی سورس نیست و آوردنشون هم اخیتاری هست(ولی زیاده کاری هست)
کد معادل:
کد php:
using UnityEngine;
using System.Collections;

public class 
NewBehaviourScript UnityEngine.MonoBehaviour {
    
    
// Use this for initialization
    
void Start () {
        
UnityEngine.Debug.Log("Hello promakers.ir");
    }
    
    
// Update is called once per frame
    
void Update () {
        
    }

کد معادل دیگه :
کد php:
using UnityEngine;
using System.Collections;

public class 
NewBehaviourScript MonoBehaviour {
    
    
// Use this for initialization
    
void Start () {
        
Debug.Log("Hello promakers.ir");
    }
    
    
// Update is called once per frame
    
void Update () {
        
    }

روی کدها نگاه کنید تا بیشتر درک کنید.
--
از تفاوت های دیگه زبان js و سیشارپ اینه که توی js متغیرها رو به این صورت تعریف می کنیم:
کد:
var varName:varType[=defaultVal];
در js ابتدا اسم متغیر می یاد بعشد دو نقطه افقی(smiley و بعدش نوع متغیر.
قسمتی که توی [] اوردم شال مقدار پیشفرض متغیر میشه و اختیاری هست. توضیح هم نمی دم روی کد چون اسم خوبی گذاشتم به فارسی انگلیسی(فینگلیش) واضح هست.

در سیشارپ اول نوع متغیر میاد و بعدش اسم متغیر و بعدش علامت انتساب(=) و بعدش مقدار پیش فرض که مساوی و مقدار دادن اختیاری هست. قبل از نوع متغیر هم میشه کلمات public و private رو اورد که به معنی سراسری و خصوصی هست. فرقشون اینه که متغیر سراسری در تمام توابع شناخته شده هست و می تونیم به مقدار اون متغیر دسترسی داشته باشیم ولی نوع خصوصی فقط داخل همون تابع.
مثال :
کد:
public bool render_mesh_normaly = true;
private bool render_lines_1st = true;


نکته آخر: یاد گیری زبان های js و csharp بسیار ساده است ولی احتیاج به دانش کلی داره. وقتی کل ساختار یک زبان رو یاد بگیریم دیگه نیازی به حفظ کردن نداریم. کافیه الگو رو از اینترنت درآریم و نحوه ی استفاده از اونا رو درک کنیم . یا یک مثال ببینیم و کمی تحقیق کنیم.
معمولا زمانی که برامون سوالی پیش می یاد بسته به اون سوالمون سعی می کنیم در امر یادگیری پیش روی کنیم در غیر اینصورت اگه بخوایم کل زبان سیشارپ و تمامی مسائل رو حل کنیم باید بگم یک شبه نمیشه. شما ساختار سی پلاس پلاس رو یاد بگیرید بعدش بیاید ببینید سیشارپ چقدر آسونه.

یکی از خصوصیات دیگه ی سیشارپ و قدرتش نسبت به cPP اینه که مثلا وقتی می خوایم تبدیل متغیر انجام بدیم می تونیم بعد از اسم اون متغیر یه نقطه بذارم و بعدش تابع مورد نظر رو انتخاب کنیم. چون خود اسم متغیرها هم نوعی کلاس محسوب می شن که زیر توابعی عضو خودشون دارن . مثلا اگه متغیری از نوع int تعریف کرده باشیم به اسم number برای تبدیلش به رشته ی عددی و برگشت مقدار تبدیل شده می نویسیم num.toString() و و یا تبدیل float به int می نویسیم varName.toByte() و الی آخر.teeth

در مورود خوندن کتاب هم خیلیا مراجعه می کنن باید بگم فقط زبان c و cpp و سپس js رو درک کنید دیگه همه چیز زیبامیشه براتون.

من حتی سیشارپ رو خوب نمی دونستم و کمی فکر کردم دیدم همون CPP هست ولی با قابلیت های تازه تر (در حقیقت سیشارپ ورژن جدید CPP هست از نظر من و اگر چه اینطور نیست و CPP یه جاهایی لازمه ولی به هر حال نظر شخصیمه و فعلا بپذیرید)

البته این مباحث پایه رو نمی خوام درس بدم ولی بازم به خاطر تاکید یکی از دوستان به ناچار اینا رو آوردم. بقیه مباحث ساده و پایه رو در تاپیک آقای راد بپرسید تا او بخش هم فعال باشه:
http://promakers.ir/showthread.php?tid=10097

موفق باشید
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#27
رفع مشکل رد شدن کاراکتر از دیوار و اشیاء دیگر
گاهی وقتا که می بینید اشیا یا player از دیوار و غیره عبور می کنن و برای شما حرفه ای ها هم ممکنه پیش بیاد که یادتون بره کالیدر رو.
به جای meshe collider پیشفرض خود مش (مدل) هایی که import می کنید به یونیتی ، از کالیدرهای خود یونیتی استفاده کنید(مثل box collider ، sphere collider , ...)
آموزش رو توی انجمن پیدا کنید خودتونwink
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#28
مقدمه ای بر شیدر نویسی در یونیتی:
نویسنده: Nikita Zakharchenko
مترجم فارسی : sajjad3011
--
resim
منبع :
http://blog.heyworks.com/tutorial-writin...n-unity3d/
مترجم: sajjad3011
--
می خواید بدونید کارت گرافیک،چطوری یه عکس رو render می کنه؟ عکس زیر ، فرایند کار رو نمایش میده:
resim
resim
resim
--
Graphics Rendering Pipeline :
یک خط لوله(pipeline ) هست که داده ها قبل از رندر روی screen ، از آن عبور می کنند. کامپیوترهای نسل قدیم از رندر نرم افزاری (software rendering) استفاده می کردند.
GPU(واحد محاسباتی داخل کارت گرافیک که پردازش های گرافیک را به عهده گرفته و بار CPU را کم می کند)، با پیروی از پایپلاین رندرینگ،همه ی محاسبات را انجام می دهد.( بقیه تاریخچه رو بیخیال)

تعریف Shader :
شیدر برنامه ای است که stage ها یا مراحل رندرینگ گرافیکی پایپ لاین را انجام می دهد.(نکته مترجم: اگه مفهوم پایپ لاین رو نمی دونید باید درس معماری کامپیوتر رو پاس کنید در غیراینصورت بهتره ازم بپرسید )

همه ی شیدرها به دو گروه تقسیم می شن:
vertice
fragment( یا pixel)

ساده ترین روش شیدر نویسی در یونیتی Surface Shader هست. طی کامپایل Surface shader ، کامپایلر شیدری تولید می کنه که شامل دو شیدر vertice و pixel هست. Unity برای شیدر نویسی زبون خاص خودشو داره.

زبون شیدر نویسی در یونیتی ShaderLab نام داره که از نوشتن کد CG و HLSL حمایت می کند.

مثال : mix shader ای بسازید که ترکیبی از diffuse texture و normal map و specular map (یا مبتنی بر Cubemap) روی یک ابجکت بگیره و پیکسل ها رو با کانال آلفا داخل diffuse texture برش بزنه.

وقتی با استفاده از CG و HLSL یک شیدر می نویسیم باید ساختار ShaderLab رو بلد باشیم.

ساختار ShaderLab اینطوریه :

کد php:
Shader"Group/SomeShader"
 
{
    
// properties that will be seen in the inspector
    
Properties
    
{
             
_Color("Main Color",Color)=(1,0.5,0.5,1)
    }
        
// define one subshader
    
SubShader
    
{
         
Pass
       
{
           }
    }
  
Fallback"Diffuse"
 


ابتدا کلمه ی کلیدی «Shader» و سپس اسم شیدر رو می نویسیم. معادل اسم شیدر یک منو توی inspector در بخش متریال ها ایجاد میشه. بعد از علامت اسلش( ‘/’) اسم زیر منوی دلخواه رو مینویسیم.

پارامترهایی که در قسمت properties تعریف میشن در inspector برا تنظیمات کاربری ظاهر خواهند شد.

هر شیدر در یونیتی از چند زیر شیدر یا sub shader تشکیل میشه.

وقتی Unity بخواد یک mesh (مدل) رو نمایش بده شیدر مورد استفاده رو جستجو می کنه و اولین ساب شیدری رو که روی کارت گرافیک کاربر اجرا میشه بر میداره. این عملیات برای این انجام میشه که یک شیدر باید بتونه روی کارت گرافیک های

مختلف که از انواع شیدر حمایت می کنند به طور دقیق اجرا بشه.(اگه این قسمت رو بد ترجمه کردم ببخشید)

بلاک Pass ، هندسه ی ابجکت رو فقط یکبار برای رندرشدن تولید می کنه.ممکنه شامب یک یا چند گذر باشه(در اصطلاح می گیم pass)

گذرهای چندتایی،باعث بهینه سازی اجرای عملیات رندر روی سخت افزارهای قدیمی و ایجاد جلوه های ویژه میشن.

چنانچه unity برای ترسیم دقیق هندسی، هیچ ساب شیدری رو در بدنه ی یک شیدر پیدا نکنه به یک شیدر دیگه در بخش Fallback رجوع ی کنه(در اصلاح می گیم roll back می کنه)


شیدر مثال بالا اگه کارت گرافیک نتونه شیدر جاری رو به درستی نمایش بده ،از یک Diffuse shader استفاده می کنه.

مثال زیر رو ببینید:

کد php:
Shader "Example/Bumped Reflection Clip"
  
{
   
Properties
   
{
    
_MainTex ("Texture"2D) = "white" {}
    
_BumpMap ("Bumpmap"2D) = "bump"  {}
    
_Cube ("Cubemap"CUBE) = "" {}
    
_Value ("Reflection Power"Range(0,1)) = 0.5
   
}

  
SubShader
  
{
   
Tags {"RenderType" "Opaque" }
   
Cull Off

   CGPROGRAM
   
#pragma surface surf Lambert
   
struct Input
   
{
    
float2 uv_MainTex;
    
float2 uv_BumpMap;
    
float3 worldRefl;
    
INTERNAL_DATA
   
};
   
sampler2D _MainTex;
   
sampler2D _BumpMap;
   
samplerCUBE _Cube;
   
float _Value;

   
void surf (Input INinout SurfaceOutput o)
   {
    
float4 tex tex2D (_MainTexIN.uv_MainTex);
    
clip (tex.0.5);
    
o.Albedo tex.rgb;
    
o.Normal UnpackNormal (tex2D (_BumpMapIN.uv_BumpMap));
    
float4 refl texCUBE (_CubeWorldReflectionVector (INo.Normal));
    
o.Emission refl.rgb _Value refl.a;
   }
  
ENDCG
 
}
 
Fallback "Diffuse"


قسمت Properties شامل 4 متغیر هست که در inspector نمایان خواهند شد.

_MainTex اس شیدر رو که قراره توی inspector دیده بشهتعریف می کنه.

_MainTex و _BumpMap ، تکستچر می گیرن.

_Cube : کیوب مپ یا Cubemap برای انعکاس(reflection)

_Value : میزان reflection (بازتابی)رو تنظیم می کنه.

Tag {“RenderType” = “Opaque”} : شیدر رو به صورت مات و کدر می کنه و روی دنباله ی drawing تاثیر می ذاره.

Cull Off : باعث disable کردن یا از کار انداختن culling می شه.-تمام face ها مستقل از جهات polygons facing رسم(draw) می شن، سه آپشن وجود داره:
* Back : این حالت پیشفرض هست و پولیگان های دور از بیننده رو رندر نمی کنه.
* Front : پولیگان های به سمت بیننده رو رندر نمی کنه.برای برگشت یا return اشیا به داخل و خارج بکار می ره.
* Off : عمل culling (حذف) رو از غیرفعال می کنه. باعث رسم همه ی face ها میشه.برای جلوه های ویژه بکار میره.


ما بلاکی از CG code رو بکار می بریم که با کلمه ی کلیدی CGPROGRAM شروع و با کلمه ی کلیدی ENDCG تمام میشه.

* pragma surface surf Lambert : تعریف تابع surface-shader به همراه بعضی از پارامترها. در این حالت، یک تابع surf داریم و مدل نوری لامبرت Lambert Lighting Model به عنوان یک پارامتر اضافی هست.

حال، ساختار Input رو شرح می دیم. تمام متغیرهای امکان پذیر ساختار Input در این ساختار قابل دسترسی می باشند. ولی من فقط اونایی رو که در مثال بالا اومده شرح می دم.(نکته: علت اینکه بیشتر توضیح نمی دم اینه که توی متی که دارم

ترجمه می کنم همینقدر گفته)

uv_MainTex و uv_BumpMap مختصات UV مناسب برای جایگذاری texture روی یک ابجکت هستند. این نام ها باید مثل نامگذاری متغیرهای تکستچر، دارای پیشوند uv_ یا uv2_ برای کانال های اول و دوم باشند. worldRefl و INTERNAL_DATA برای

رفلکشن (بازتاب)ها بکار می رن.

حالا اجازه بدید تابع شیدر surf رو شرح بدیم:

ما در مرحله ی اول برداری با 4 کامپوننت رو در ساختار output مربوط به UV-map دریافت می کنیم(RGB + Alpha) . متغیر text اطلاعات مربوط به این ساختار رو نگه داری می کنه.
سپس در خط بعدی با استفاده از تابع clip مشخص می کنیم که کدام پیکسل ها باید از خروجی حذف شوند.
ما پس از استقرار cut-off روی اطلاعات ذخیره شده در alpha channel، از tex.a به عنوان یک پارامتر استفاده می کنیم.

پس از cull off تکستچر اصلی را با استفاده از یک خط کد روی ابجکت خود رسم می کنیم:
کد:
o.Albedo = tex.rgb;
متغیر o دارای ساختار output می باشد.(نکته: کسانی که ساختار رو نمی دونن چیه باید مفهوم structure در زبان C رو برن یاد بگیرن. بلد نبودین پرس و جو کنید) . همه ی فیلدهای این ساختار در Help بخش SurfaceShaders توصیف شده است.
سپس ،در مرحله ی بعدی نرمال مپ رو apply می کنیم:
کد:
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
سپس بازتابی یا reflection رو اضافه می کنیم:
کد:
float4 refl = texCUBE (_Cube, WorldReflectionVector (IN, o.Normal));
o.Emission = refl.rgb * _Value * refl.a;

نیاز به تذکر است ، ما با استفاده از اطلاعاتی در مورد بازتابی که به وسیله ی پارامتر _Value ضرب می گردد،می توانیم میزان افکت یا efect level رو در کادر خصوصیات inspector کنترل کنیم.

در انتها، Fallback را برای حالتی می نویسیم که کارت گرافیک قادر به رسم دقیق شیدر نباشد.smiley
-
از دیشب تا صبح بیدار موندم تا این همه ترجمه کنم براتون ، اگه استقبال بشه در مورد شیدرها خیلی چیزای قشنگ دیگه هم ترجمه می کنم wink
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#29
ایجاد شیدر car paint برای نقاشی روی ماشین :
در پنجره project راست کلیک کرده و create->shader و سپس روی شیدر ایجاد شده دابل کلیک کنید تا وارد mono editor یونیتی بشیم.
کد زیر رو جایگزین کنید.
کد php:
Shader "Elementals/Reflection Blur Fresnel"
{
    
Properties
    
{
        
_MainTint ("Main Tint"Color) = (0.5,0.5,0.5,0.5)
        
_MainTex ("Texture"2D) = "white" {}
        
_NormalMap ("Normal Map"2D) = "bump" {}
        
_SpecularMap("Specular Map"2D) = "white" {}
        
_Cube ("Cubemap"CUBE) = "" {}  
        
_ReflectionMap ("Reflection Map"2D) = "white" {}
        
_Blur ("Blur"Float) = 0.5  
        
        _SpecColor 
("Specular Color"Color) = (0.5,0.5,0.5,1)
        
_Shininess ("Shininess"Range (0.011)) = 0.078125 

        _RimColor
("Rim Color"Color) = (1,0,0,1)
        
_RimPower("Rim Power"Float) = 100

        _FresIn
("Fresnel Mid"Range(0.0011.0)) = 0.25
        _FresOut
("Fresnel Zovniwn"Range(0.0011.0)) = 0.25
    

    
    
SubShader
    
{
        
Tags "RenderType" "Opaque" }
        
CGPROGRAM 
        
#pragma surface surf  Sram 
        #pragma glsl
        #pragma target 3.0 
        
        
float _Blur;
        
float _BlurType;
        
float _BlurRange;
        
fixed _ReflPower
        
        
float _Shininess
        
float _SpecPower;
        
        
float4 _FresColor;
        
fixed _FresPowerIn;
        
fixed _FresPowerOut;
        
fixed _FresIn;
        
fixed _FresOut;
                
        
fixed4 _MainTint;
        
float4 _RimColor
        
float _RimPower
        
        
struct Input
        
{
            
float2 uv_MainTex;
            
float2 uv_NormalMap
            
float2 uv_SpecularMap
            
float2 uv_ReflectionMap;
            
float3 worldRefl;
            
float3 viewDir
            
INTERNAL_DATA
        
}; 
        
        
sampler2D _MainTex;
        
sampler2D _NormalMap;
        
sampler2D _SpecularMap;
        
sampler2D _ReflectionMap;
        
samplerCUBE _Cube;  
        
float4 refl;
        
        
inline fixed4 LightingSram(SurfaceOutput sfixed3 lightDirfixed3 viewDirfixed atten)
        {
            
fixed3 halfVector normalize(lightDir viewDir);
        
            
fixed NdotL max(0dot(s.NormallightDir));
            
            
fixed EdotH max(0dot(viewDirhalfVector));
            
fixed NdotH max(0dot(s.NormalhalfVector));
            
fixed NdotE max(0dot(s.NormalviewDir));
            
            
//Rim light  
            
fixed rimLight 0;
            
rimLight pow(rimLight_RimPower) * NdotH;
             
            
float spec pow (NdotHs.Specular*128.0) * s.Gloss;
            
            
fixed4 finalColor;
            
finalColor.rgb = (s.Albedo _LightColor0.rgb NdotL +  _LightColor0.rgb spec _SpecColor rimLight) * (NdotE atten 2);
            return 
finalColor;
        } 
        
        
float4 ReflectionBlurCube(samplerCUBE CubeTexfloat3 refVectorfloat _Blur)
        {
            
_BlurRange _Blur/10;
                
refl += texCUBE (CubeTexrefVector float3(4*_BlurRange,0,0))*0.05;
                
refl += texCUBE (CubeTexrefVector float3(3*_BlurRange,0,0))*0.09;
                
refl += texCUBE (CubeTexrefVector -float3(2*_BlurRange,0,0))*0.12;
                
refl += texCUBE (CubeTexrefVector -float3(1*_BlurRange,0,0))*0.15;
                
refl += texCUBE (CubeTexrefVector ) * 0.16;
                
refl += texCUBE (CubeTexrefVector float3(1*_BlurRange,0,0))*0.15;
                
refl += texCUBE (CubeTexrefVector float3(2*_BlurRange,0,0))*0.12;
                
refl += texCUBE (CubeTexrefVector float3(3*_BlurRange,0,0))*0.09;
                
refl += texCUBE (CubeTexrefVector float3(4*_BlurRange,0,0))*0.05;
    
//                refl += texCUBE (CubeTex, refVector -float3(0,4*_BlurRange,0))*0.05;
//                refl += texCUBE (CubeTex, refVector -float3(0,3*_BlurRange,0))*0.09;
//                refl += texCUBE (CubeTex, refVector -float3(0,2*_BlurRange,0))*0.12;
//                refl += texCUBE (CubeTex, refVector -float3(0,1*_BlurRange,0))*0.15;
//                refl += texCUBE (CubeTex, refVector ) * 0.16;
//                refl += texCUBE (CubeTex, refVector +float3(0,1*_BlurRange,0))*0.15;
//                refl += texCUBE (CubeTex, refVector +float3(0,2*_BlurRange,0))*0.12;
//                refl += texCUBE (CubeTex, refVector +float3(0,3*_BlurRange,0))*0.09;
//                refl += texCUBE (CubeTex, refVector +float3(0,4*_BlurRange,0))*0.05;
//    
//                refl += texCUBE (CubeTex, refVector - float3(0,0,4*_BlurRange))*0.05;
//                refl += texCUBE (CubeTex, refVector - float3(0,0,3*_BlurRange))*0.09;
//                refl += texCUBE (CubeTex, refVector - float3(0,0,2*_BlurRange))*0.12;
//                refl += texCUBE (CubeTex, refVector - float3(0,0,1*_BlurRange))*0.15;
//                refl += texCUBE (CubeTex, refVector ) * 0.16;
//                refl += texCUBE (CubeTex, refVector + float3(0,0,1*_BlurRange))*0.15;
//                refl += texCUBE (CubeTex, refVector + float3(0,0,2*_BlurRange))*0.12;
//                refl += texCUBE (CubeTex, refVector + float3(0,0,3*_BlurRange))*0.09;
//                refl += texCUBE (CubeTex, refVector + float3(0,0,4*_BlurRange))*0.05;
    
//                refl += texCUBElod (CubeTex, float4(refVector - float3(4*_BlurRange,0,0), _Blur))*0.05;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(3*_BlurRange,0,0), _Blur))*0.09;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(2*_BlurRange,0,0), _Blur))*0.12;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(1*_BlurRange,0,0), _Blur))*0.15;
//                refl += texCUBElod (CubeTex, float4(refVector , _Blur)) * 0.16;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(1*_BlurRange,0,0), _Blur))*0.15;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(2*_BlurRange,0,0), _Blur))*0.12;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(3*_BlurRange,0,0), _Blur))*0.09;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(4*_BlurRange,0,0), _Blur))*0.05;
//    
//                refl += texCUBElod (CubeTex, float4(refVector - float3(0,4*_BlurRange,0), _Blur))*0.05;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(0,3*_BlurRange,0), _Blur))*0.09;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(0,2*_BlurRange,0), _Blur))*0.12;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(0,1*_BlurRange,0), _Blur))*0.15;
//                refl += texCUBElod (CubeTex, float4(refVector , _Blur)) * 0.16;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(0,1*_BlurRange,0), _Blur))*0.15;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(0,2*_BlurRange,0), _Blur))*0.12;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(0,3*_BlurRange,0), _Blur))*0.09;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(0,4*_BlurRange,0), _Blur))*0.05;
//    
//                refl += texCUBElod (CubeTex, float4(refVector - float3(0,0,4*_BlurRange), _Blur))*0.05;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(0,0,3*_BlurRange), _Blur))*0.09;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(0,0,2*_BlurRange), _Blur))*0.12;
//                refl += texCUBElod (CubeTex, float4(refVector - float3(0,0,1*_BlurRange), _Blur))*0.15;
//                refl += texCUBElod (CubeTex, float4(refVector , _Blur)) * 0.16;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(0,0,1*_BlurRange), _Blur))*0.15;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(0,0,2*_BlurRange), _Blur))*0.12;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(0,0,3*_BlurRange), _Blur))*0.09;
//                refl += texCUBElod (CubeTex, float4(refVector + float3(0,0,4*_BlurRange), _Blur))*0.05;
             
                //return refl/3 ;//* _ReflPower;
                //refl = texCUBE (CubeTex, refVector);
                
return refl ;//* _ReflPower;
        
}
        
        
void surf (Input INinout SurfaceOutput o)
        { 
            
half4 c tex2D (_MainTexIN.uv_MainTex);
            
o.Albedo c.rgb _MainTint c.c.rgb *(1c.a);
            
half4 g tex2D (_SpecularMapIN.uv_SpecularMap);
            
o.Gloss g.r;
            
o.Specular _Shininess
            
o.Normal UnpackNormal (tex2D (_NormalMapIN.uv_NormalMap)); 
            
            
_ReflPower tex2D (_ReflectionMapIN.uv_ReflectionMap).r;
                                    
             
half rim saturate(dot(normalize(IN.viewDir), o.Normal));
             
half fr1 saturate(dot(normalize(IN.viewDir), o.Normal));
             
half fr2 saturate(dot(normalize(IN.viewDir), o.Normal));

            
float4 bluredReflection ReflectionBlurCube(_Cube,WorldReflectionVector (INo.Normal),_Blur);
            
o.Emission bluredReflection _ReflPower *_FresOut pow(fr11) + 
                         
bluredReflection _ReflPower *_FresIn pow(fr21) + 
                         
_RimColor.rgb pow(rim_RimPower)*_RimColor.a;
        }
        
ENDCG
    

    
Fallback "Diffuse"

کد رو ذخیره کنید .
به محیط یونیتی برگردید و یه new material ایجاد کنید و سپس شیدر ایجاد شده رو توی کادر پروژه با ماوس بکشید بندازید ری این متریال تا set بشه.
سپس متریال رو بندازی روی ابجکت دلخواه.

بخش properties از کد شیدر رو نگاه کنید:
resim
13 تا پارامتر از ورودی می گیریم. این ورودی ها کجان ؟
پاسخ:
متریال رو انتخاب کنید می بینید 10 پارامتر در inspector ایجاد شده.

می تونید تنظیم کنید و تکستچرهای bumped و ... رنگ و غیره رو تنظیم کنید:
resim
یک تکستچر متال(فلز) بندازید روی main texture و یک تکستچر نرمال مپ بندازید روی پارامتر nornaml map .
نکته: ساخت تکستچر نرمال مپ فقط با چند کلیک در نرم افزار crazy bumped صورت می گیره.
حالا تسکتچرهای دیگه هم ندادید زیاد مهم نیست ولی نرمال مپ واسه ایجاد بجستگی ها و طبیعی جلوه کردن بکار می ره.سوال بود بپرسید.
پارامتر tint واسه رنگ tint یا رنگ سیری (یه رنگ ایجاد انعکاس) روی ماشین بکار میره.
نمونه خروجی:
resim
تا چند ثانیه دیگه یه کلیپ هم میذارم تا ببینید قدرت روwink

اینم کلیپ(کیفیت رو خیلی اوردم پایین تا بشه 2 مگ، ویلا 12 مگ بود ):
http://s5.picofile.com/file/8154744884/s..._.zip.html
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ
#30
Gyroscope Controller (چرخش موبایل و افقی و عمودی شدن بازی) برای unity3d
resim
منبع:
http://blog.heyworks.com/how-to-write-gy...h-unity3d/
مترجم:sajjad3011
--
برای اینکار باید دوربین اصلی رو با استفاده از کد به طور مناسب و بدون هیچ لرزش قابل توجهی چرخش بدیمsmiley
این اسکریپت، محور بالای جهان مجازی را به موازات محور بالای جهان واقعی نگه داشته و از نو ، چرخش افقی را درجه بندی می کند.
مسئله ای که ما حل می کنیم دارای انواع سیستم های مختصات مرجع مختلف در دستگاه iOS در unity3d است: چپ دست و راست دست.

برای تبدیل quaternion( سیستم 4 تایی) از یک سیستم به سیستم دیگر، از تابع زیر استفاده می کنیم:
کد php:
private static Quaternion ConvertRotation(Quaternion q)
{
    return new 
Quaternion(q.xq.y, -q.z, -q.w);


سپس از کد زیر برای حاسبه ی چرخش دوربین استفاده می کنیم:
کد php:
transform.rotation ConvertRotation(Input.gyro.attitude); 
مشکل بعدی با مقداردهی برای ساپورت روی گوشی های مختلف هست. این مشکل توسط سازندگان خود یونیتی در ورژن Unity 4 به بالا حل شد . با تابع زیر این کار صورت می گیرد:
کد php:
private Quaternion GetRotFix()
{
    if (
Screen.orientation == ScreenOrientation.Portrait)
        return 
Quaternion.identity;
    if (
Screen.orientation == ScreenOrientation.LandscapeLeft
    
|| Screen.orientation == ScreenOrientation.Landscape)
        return 
Quaternion.Euler(00, -90);
    if (
Screen.orientation == ScreenOrientation.LandscapeRight)
        return 
Quaternion.Euler(0090);
    if (
Screen.orientation == ScreenOrientation.PortraitUpsideDown)
        return 
Quaternion.Euler(00180);
    return 
Quaternion.identity;

و در زیر، تابع آپدیت شده برای محاسبه ی چرخش دوربین را می بینیم:
کد php:
transform.rotation ConvertRotation(Input.gyro.attitude) * GetRotFix(); 
اسکریپت کنترلر، باید دوربین رو مناسب با چرخش موبایل ، آپدیت و در سطح افقی reset کنه. یعنی برای مثال اگه کاربر گوشی رو به سمت شمال نگه داره گوشی باید به طور خودکار جهت شمال مجازی رو تنظیم کنه و دوربین جهت و direction داده شده رو نشون بده.
در زیر اسکریپیتی مبتنی بر چرخش دستگاه و تنظیم دوربین اکانت (account) رو میبینید:
کد php:
transform.rotation cameraBase * ( ConvertRotation(referenceRotation Input.gyro.attitude) * GetRotFix(); 
محاسبات cameraBase و referanceRotation یک حقه است. اینجا دو مشکل اصلی داریم:
* شما باید برای محاسبه ی referenceRotation، به جهت دستگاه موبایل خودتون دسترسی داشته باشید.
* شما باید برای محاسبه ی cameraBase ،فقط به چرخش حول محور بالا(Up) دسترسی داشته باشید.


توابع دقیقی برای مثال پیوست شده وجود دارد.
و آخرین چیز moothing camera rotation (چرخش نرم دوربین) هست که با استفاده از دستور Slerp این کار رو انجام می دیم
کد php:
transform.rotation Quaternion.Slerp(transform.rotationcameraBase * ( ConvertRotation(referanceRotation Input.gyro.attitude) * GetRotFix()), lowPassFilterFactor); 

نکته ی مترجم(sajjad3011): تابع lerp رو توی درسای قبلی همین تاپیک یاد دادم که چه قدرتی داره و چقدر کار باهاش قشنگه. برای درک slerp فقط کافیه همون Lerp رو که یادتون دادم بخونیدsmiley

حالا اجازه بدید دو تابع AttachGyro و DetachGyro رو هم اضافه کنیم.
اولی، کنترلر رو enable(فعال) و تمام چرخش های اصلی رو re calculate (از نو محاسبه) می کنه.
دومی،کنترلر رو از کار میندازه(disable می کنه)teeth

سرانجام کنترلر ما آماده میشهteeth . لطفا مثال پیوست را دانلود کنید. سازندش می گه من از پیام ها و قدردانی ها و سوالات شما تشکر می کنم. امیدوارم این پست برای شما مفید بوده باشه teeth

دانلود مثال:
http://blog.heyworks.com/wp-content/uplo...typackage/
پسوندش بعد از دانلود ممکنه حذف بشه. خودتون پسوند رو به unitypackage تغییر بدید.
https://telegram.me/gameoverblog

من به سرچشمه خورشید نه خود بردم راه/ذره ای بودم و مهر تو مرا بالا برد
من خسی بی سرو پایم که به سیل افتادم/او که می رفت مرا هم به دل دریا برد


پاسخ




کاربرانِ درحال بازدید از این موضوع: 1 مهمان