درود مهمان گرامی! ثبت نام

ساخت بازی

امتیاز موضوع:
  • 6 رأی - میانگین امتیازات: 4.67
  • 1
  • 2
  • 3
  • 4
  • 5
برنامه نویسی و راهکارهایی در یونیتی
#11
نکته: بعضی وقتا در فضای و بعدی ممکنه رویداد onMouseDown درست عمل نکنه و برای رفع این اشکال شما کافیه کدتون رو برای خطایابی در محیط 3d به جای 2d تست کنید.wink
https://telegram.me/gameoverblog
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



پاسخ
 سپاس شده توسط AliScan ، محمدمهدی علیجانی ، Amirns ، moien1 ، King of Power ، aliheadari ، Sajjad_everwake ، raamz110
#12
نکته : اگر با خطایی مثل این مواجه شدید بدونید که اسم کلاس و اسم اسکریپت شما نباید همچین اسمی باشه و rename اش کنید چون اسم انتخابی شما جزو namespace هست یا به عبارت دیگه در فضای نام(حافظه ی توکار یونیتی برای ذخیره بعضی از سرنام ها) از قبل تعریف شده و شما مجاز نیستید به استفاده دوباره از این اسم در بعضی جاها.
کد:
The namespace `global::' already contains a definition for "یه اسم که واسه کلاستون گذاشتید"
https://telegram.me/gameoverblog
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



پاسخ
 سپاس شده توسط محمدمهدی علیجانی ، Amirns ، King of Power ، aliheadari
#13
تکنیک متحرک سازی اسپرایت های برش خورده ی دو بعدی بر حسب زمان :
resim

یک پروژه با نوع 2D ایجاد کنید.(موقع ایجاد type رو بذارید روی 2D)

و یک اسپرایت (عکس) PNG رو با فتوشاپ طراحی کردیم که 4 تا فریم برای راه رفتن کاراکتر دو بعدی از نمای بالا هست.
اگه بلد نیستید اینو دانلود کنید :

http://cdn3.raywenderlich.com/wp-content...zombie.png
resim

این png رو بکشید توی کادر پروژه.
من با paint این png رو باز کردم و با ctrl+E بهتون نشون دادم ابعاد این png رو :

resim

می بینید پهنای عکس ما 628 و ارتفاعش 102 پیکسل هست.

از اونجا که 4 تا فریم داریم پس اگه بخوایم توی یونیتی این تکه ها رو برش بزنیم باید 628 رو تقسیم به 4 کنیم که میشه 157

پس هر فریم باید ارتفاعش 102 (ارتفاع تغییر نکرد) و عرضش 157 باشه و الان می گم چطوری توی یونیتی باید این کار رو انجام بدیم.smiley

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

می بینید یه آیتم برای ویرایش در اختیارتون قرار می گیره . روی sprite Editor در پنجره ی خصوصیات (inspector)کلیک کنید تا به پنجره ی ویرایش بریمwink

توی کادر Sprite Editor روی گزینه ی slice بزنید(slice به معنی برش هست)

Type روی Automatic هست و لولا(pivot) روی مرکز(center) . اگه روی دکمه Slice بزنید خودکار ایتم هایی که بینشون فاصله خالی هست رو پیدا و برش می زنه و اندیس گذاری می کنه(شروع از 0 هست)

منتها ما چون می خوایم اندازه رو دقیق بدیم Type رو بذارید روی Grid و pixel Size رو برای x و y همون 157 و 102 رو بدید.
من توی عکس نشون دادم:
http://s5.picofile.com/file/8153253668/s...editor.jpg
resim

بعد از برش زدن، پنجره sprite editor رو ببندید و Apply کنید.smiley

خوب اسپرایت ما فریم بندی شده و حالا باید اونو به صحنه ببریم و کدنویسی رو انجام بدیم.

یه کپی از اون رو بکشید بندازید توی صحنه یا hierarchy(کادر اجزای صحنه/مرحله یا level هر چی دوست دارید بگید)

یه اسکریپت سیشارپ بسازید و اسمشو بذارید script1 و بازش کنید.

قبل از تابع Start متغیرها رو به این صورت تعریف کنید :

کد php:
    public Sprite[] sprites;
    private 
SpriteRenderer spriteRenderer;
    public 
float framesPerSecond

سپس باید نوع رندر کننده رو روی SpriteRenderer تنظیم کنیم. برای اینکار در تابع Start (که جکم رویداد create گیم میکر رو داره)این کد رو میذاریم:

کد php:
spriteRenderer renderer as SpriteRenderer

در تابع Update هم این کد رو بذارید :
کد php:
        int index = (int)(Time.timeSinceLevelLoad framesPerSecond);
        
index index sprites.Length;
        
spriteRenderer.sprite spritesindex ]; 
کد بالا سخت نیست ولی چون بعضیا گیج میشن توضیح میدم.
می دونید تابع upate لحظه به لحظه قراره اجرا بشه و باید بین فریم ها سوئیچ کنیم و این عمل رو تکرار کنیم.
ولی این کار ممکنه خیلی سریع باشه پس برای اینکه یه تاخیر یا delay ایجاد بشه یه فرمول کلی در آوردیم.
دستور Time.timeSinceLevelLoad هم یه دستور تعریف شده ی یونیتی هست که هر تغییری که ایجاد میشه آخرین زمان رو میده و هی داره عددش زیاد میشه و یه اعدد اعشاری از نوع float هست که حالا زیاد مهم نیست روش بحث کنیم(ما فقط قسمت صحیح رو جدا می کنیم با دستور int )
sprites.Length طول یا تعداد فریم ها رو میده که 4 تا هست ولی ما 6 تاش می کنیم که بعدا می گم واسه چی. شما هم از الان فرض کنید 4 تا هست.

علامت درصد برای محاسبه ی باقیمانده ی تقسیم متغیر index به sprite.Length بکار می ره(علامت درصد % دستوری از خانواده ی زبان C هست که برای محاسبه ی باقیمانده حاصل از تقسیم بکار می ره)

توی تقسیم فوق index مطمئن باشید عدد صحیح میشه و از 0 شروع میشه و بعدش 1 و ... و آخرش همون sprites.Length میشه و بازم از 0 تکرار میشه و تو خط بعدی یعنی
کد:
        spriteRenderer.sprite = sprites[ index ];
باعث میشه فریم set بشه روی رندر کننده ی اسپرایت.

حالا توضیح میدم چرا باید Length رو 6 تا فرض کنیم.
ما باید اندیس اسپرایت رو طوری تغییر بدیم که یه جوری به نظر بیاد که طرف فکر کنه داره راه میره. برای اینکار ابتدا باید فریم ترتیب تکرار رو در بخش design به تکنیک دلخواه تعریف کنیم. مثلا ابتدا فریم 0و1و2و3 رو اجرا و سپس فریم 2و 1 رو اجرا می کنیم و وقتی تموم شد بعد از 1 خودش طبعا باید بره روی فریم 0 و از اول. اگه یکم فکر کنید می بنید در حقیقت یه جور از اول به آخر رفتن و سپس یه جوری از آخر به اول اومدن هست و یه جور تکرار که انگار کاراکتر داره راه میره.

برای اینکار اسپرایت زامبی رو در صحنه ( hierarchy) انتخاب کنید . توی کادر inspector خصوصیت Sprites رو در زیرشاخه ی اسکریپت اضافه شده می بینید.

گزینه ی Size رو بذارید روی 6 تا 6 تا فریم که قبلا توضیح دادم ایجاد بشه (Eemen0 تا Element5)

سپس برش های 0 تا 4 رو روی Elemen0 تا Element4 بکشید رها کنید و همینطور برش 2 رو روی Element4 و برش 1 رو روی Element5 بکشید و رها کنید.
http://s5.picofile.com/file/8153261400/length.jpg
resim

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

گرچه هنوز کدنویسی راه رفتنش مونده که اونم یادتون خواهم داد ولی شما تا این مرحله یاد گرفتید یک اسپرایت رو مثل گیم میکر اما در unity متجرک سازی کنید.

خصوصیت Projection دوربین اصلی رو از حالت پرسپکتیو (perspective) سه بعدی بذارید روی ارتوگرافیک دو بعدی.

بعدش دوربین رو در ناحیه ای جابجا کنید که کاراکتر رو خوب نشون بده. ضمنا یک عکس هم می تونید به عنوان پس زمینه به پروژه اضافه کنید و تو صحنه پشت اسپرایت بذارید. با اینم اگه مشکل دارید توی کادر صحنه(scene) گزینه ای به اسم 2d هست که باهاش بین حالت سه بعدی و دو بعدی میشه سوئیچ کرد واسه جابجایی و راحت کاری.(مباحث دیگه ای مثل لایه ها هست که جزو این درس نیست اونا رو هم گام به گام بعدا یادتون میدم)

یادم رفت بگم سرعت حرکت حرکت بین فریم ها رو باید توی اسکریپت مقدار بدید. برای اینکار متغیر FramsePerSeconds رو تعریف کردیم که توی کادر inspector می تونید عدد 10 رو بهش بدید که یک سرعت نرمال و نسبتا خوبی هست که اگه تغییرش بدید نتیجه رو خواهید دید.
هر چی بیشتر باشه سرعت زیاد تر میشه و اگه کم بشه سرعت راه رفتن کم تر میشه. شما می تونید از این پارامتر ، برای تغییر سرعت راه رفتن و ایجاد حالت دویدن یا آرام راه رفتن استفاده کنید و خیلی کارای دیگهteeth
یادم رفت منبع رو بگم :
http://www.raywenderlich.com/61532/

ولی توضیحات رو خلاصه کردم و خیلی چیزا رو خودم توضیح دادم.

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

حرکت کاراکتر و چرخش دقیق به سمت جایی که کلیک کردیم :
resim

این اسکریپت رو کپی کنید به جای کل اسکریپتی که برای انیمیشن کردن gif مون ساختیم :
کد php:
using UnityEngine;
using System.Collections;
    public class 
script1 MonoBehaviour {
    public 
Sprite[] sprites;
    public 
float framesPerSecond;
    public 
float moveSpeed;
    private 
Vector3 moveDirection;
    private 
SpriteRenderer spriteRenderer;
    public 
float turnSpeed;
    
// Use this for initialization
    
void Start () {

        
spriteRenderer renderer as SpriteRenderer;
        
moveDirection Vector3.right;
    }
    
    
// Update is called once per frame
    
void Update () {



        
int index = (int)(Time.timeSinceLevelLoad framesPerSecond);
        
index index sprites.Length;
        
spriteRenderer.sprite spritesindex ];

        
// 1
        
Vector3 currentPosition transform.position;
        
// 2
        
if(Input.GetMouseButtonDown(0)) {
            
// 3
            
Vector3 moveToward Camera.main.ScreenToWorldPointInput.mousePosition );
            
// 4
            
moveDirection moveToward currentPosition;
            
moveDirection.0
            
moveDirection.Normalize();
        
        }

        
        
Vector3 target moveDirection moveSpeed currentPosition;
        
transform.position Vector3.LerpcurrentPositiontargetTime.deltaTime );


        
float targetAngle Mathf.Atan2(moveDirection.ymoveDirection.x) * Mathf.Rad2Deg;
        
transform.rotation 
            
Quaternion.Slerptransform.rotation
                             
Quaternion.Euler00targetAngle ), 
                             
turnSpeed Time.deltaTime );
    }


با اسکریپت فوق هر جا کلیک کنید کاراکتر خیلی دقیق چرخش می کنه و در جهت نقطه ای میره کلیک کردیم.teeth
اجرا بگیرید و تشکر یادتون نره. اسکریپت ها رو خودم ترو تمیز می کنم ویلا روی هم کردن کمی وقت می بره و من راحت کردم کار شما رو.wink
https://telegram.me/gameoverblog
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



پاسخ
 سپاس شده توسط محمدمهدی علیجانی ، Amirns ، lord arthas ، what ، AliScan ، moien1 ، King of Power ، aliheadari ، qwerty13 ، ali.fefa8888 ، Ali-reza8448v2
#14
مباحث ساده هوش مصنوعی
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
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



پاسخ
 سپاس شده توسط AliScan ، محمدمهدی علیجانی ، تور110 ، امیرحسین گیمر ، moien1 ، King of Power ، aliheadari ، UtmostGG ، qwerty13
#15
تعریف آرایه ای از گیم ابجکت :
اسکریپت خود را به زبان 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
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



پاسخ
 سپاس شده توسط محمدمهدی علیجانی ، تور110 ، امیرحسین گیمر ، moien1 ، aliheadari ، Sajjad_everwake
#16
ساخت یک موجود هوشند با استفاده از waiypoints:
resim
در بخش هوش مصنوعی درسشو دادم.به این لینک مراجعه بفرمایید:
http://promakers.ir/showthread.php?tid=8...#pid109825
https://telegram.me/gameoverblog
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



پاسخ
 سپاس شده توسط محمدمهدی علیجانی ، AliScan ، امیرحسین گیمر ، moien1 ، aliheadari ، UtmostGG ، qwerty13
#17
رندر به صورت 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
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



پاسخ
 سپاس شده توسط محمدمهدی علیجانی ، تور110 ، امیرحسین گیمر ، moien1 ، aliheadari ، qwerty13
#18
چطور سیشارپ و جاوااسکریپت رو یادبگیریم ؟
چون بچه های زیادی مشکل داشتن تصمیم گرفتم کمی توضیح بدم :
واسه یادگیری سیشارپ باید 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
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



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



پاسخ
 سپاس شده توسط تور110 ، moien1 ، aliheadari
#20
مقدمه ای بر شیدر نویسی در یونیتی:
نویسنده: 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
بیشتر از آنچه برای موفق بودن تلاش می کنی برای با ارزش بودن تلاش کن.آلبرت انیشتین.



پاسخ
 سپاس شده توسط محمدمهدی علیجانی ، moien1 ، aliheadari ، UtmostGG ، qwerty13


موضوعات مرتبط با این موضوع...
موضوع نویسنده پاسخ بازدید آخرین ارسال
  آموزش شیدر نویسی در یونیتی قسمت 1 ErfanAhmadi 15 4,727 15/3/1396، 05:53 عصر
آخرین ارسال: mamali me
  آموزش یونیتی از مبتدی تا متوسط برنامه ریزی شده amirhosein.raad 24 2,923 26/2/1396، 08:24 عصر
آخرین ارسال: TakOn1
  پرداخت درون برنامه ای بازار sajjad3011 0 360 4/10/1394، 10:41 عصر
آخرین ارسال: sajjad3011
Big Grin دانلود کتاب فارسی آموزش کامل زبان برنامه نویسی پایتون Teshne 3 1,183 19/2/1394، 06:25 عصر
آخرین ارسال: sajjad3011
Question اسکریپت نویسی در یونیتی به زبان C# soroosh 4 4,708 20/10/1393، 01:38 عصر
آخرین ارسال: Ali-reza8448



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